Registrando OpenTelemetry durante el inicio y agregando más capacidades dinámicamente durante la ejecución.
Dentro del método ConfigureServices
en la clase Startup
, estoy registrando OpenTelemetry de la siguiente manera:
services.AddOpenTelemetryTracing((builder) =>
builder
.SetResourceBuilder(ResourceBuilder.CreateDefault().AddService("MyService"))
.AddAspNetCoreInstrumentation()
.AddHttpClientInstrumentation()
.AddOtlpExporter(otlpOptions =>
{
otlpOptions.Endpoint = new Uri("http://localhost:4317");
}));
Quiero agregar también una instrumentación para Redis, pero solo tendré acceso a la cadena de conexión de Redis mientras sirva la solicitud donde extraiga el ClientId
y extraiga la cadena de conexión de Redis correspondiente a ese cliente de la configuración respectiva del cliente. Dentro de la clase Startup nuevamente, mientras leo el ClientInfo
, agrego una trazabilidad de OpenTelemetry para instrumentar las llamadas a Redis.
services.AddScoped<ClientInfo>(sp =>
{
var context = sp.GetService<IHttpContextAccessor>().HttpContext;
var clientId = context.Request.Headers["ClientId"].ToString();
var clientInfo = await GetClientInfo(clientId).Result;
// ClientInfo contendrá la cadena de conexión de Redis. Cachearé esto para no tener que buscarlo repetidamente para el mismo cliente
// Cachearé este ClientId en un diccionario y me aseguraré de que el registro a continuación suceda solo una vez por Id.
// RedisConnection es del tipo IConnectionMultiplexer
var redisConnection = RedisHelper.GetConnection(clientInfo.RedisConnectionString);
services.AddOpenTelemetryTracing((builder) =>
builder
.SetResourceBuilder(ResourceBuilder.CreateDefault().AddService("MyService"))
.AddRedisInstrumentation(redisConnection)
.AddOtlpExporter(otlpOptions =>
{
otlpOptions.Endpoint = new Uri("http://localhost:4317");
}));
return clientInfo;
});
Cuando ejecuto el código, solo crea una traza para las solicitudes HTTP entrantes y salientes, pero no instrumenta las llamadas a Redis. Sin embargo, si agrego la instrumentación para Redis en la primera llamada donde estoy registrando AddAspNetCoreInstrumentation
, entonces funciona bien.
¿Hay alguna manera de agregar cierta instrumentación durante el inicio y construir sobre eso durante el tiempo de ejecución agregando más instrumentación?
davy.ai
Sí, se puede agregar instrumentación durante el arranque y construir sobre eso durante el tiempo de ejecución agregando más instrumentación. En su caso, puede separar la lógica de instrumentación de Redis del método “ConfigureServices” y crear un servicio separado que maneje la instrumentación de Redis.
Primero, cree una interfaz para el servicio de instrumentación de Redis:
Luego, implemente la interfaz:
Observe que se está inyectando un
TracerFactory
en lugar de agregar directamente la instrumentación de OpenTelemetry en el método “ConfigureServices”. Esto nos permite obtener elTracerProvider
que se creó durante el arranque y agregar más instrumentación durante el tiempo de ejecución.Ahora, en su clase de “Startup”, cambie el código de instrumentación de Redis para usar el
IRedisInstrumentationService
:Asegúrese de registrar
RedisInstrumentationService
como un singleton en “ConfigureServices”:De esta manera, durante el arranque, solo registramos la instrumentación de ASP.NET Core y HTTP Client y obtenemos la instancia de
TracerProvider
. Luego, durante el tiempo de ejecución, usamosIRedisInstrumentationService
para agregar la instrumentación de Redis a la instancia existente deTracerProvider
.</iredisinstrumentationservice,>