es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

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?

Tags:  , ,

Answer

  1. Avatar for 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:

    public interface IRedisInstrumentationService {
        Task AddRedisInstrumentation(string redisConnectionString);
    }
    

    Luego, implemente la interfaz:

    public class RedisInstrumentationService : IRedisInstrumentationService {
        private readonly TracerFactory _tracerFactory;
    
        public RedisInstrumentationService(TracerFactory tracerFactory) {
            _tracerFactory = tracerFactory;
        }
    
        public async Task AddRedisInstrumentation(string redisConnectionString) {
            var redisConnection = RedisHelper.GetConnection(redisConnectionString);
            var tracerProvider = _tracerFactory.GetTracerProvider();
            tracerProvider.AddRedisInstrumentation(redisConnection);
        }
    }
    

    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 el TracerProvider 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:

    services.AddScoped<clientinfo>(sp =>
    {
        var context = sp.GetService<ihttpcontextaccessor>().HttpContext;
        var clientId = context.Request.Headers["ClientId"].ToString();
        var clientInfo = await GetClientInfo(clientId).Result;
    
        var redisInstrumentationService = sp.GetRequiredService<iredisinstrumentationservice>();
        redisInstrumentationService.AddRedisInstrumentation(clientInfo.RedisConnectionString);
    
        return clientInfo;
    });
    

    Asegúrese de registrar RedisInstrumentationService como un singleton en “ConfigureServices”:

    services.AddSingleton<iredisinstrumentationservice, redisinstrumentationservice="">();
    

    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, usamos IRedisInstrumentationService para agregar la instrumentación de Redis a la instancia existente de TracerProvider.</iredisinstrumentationservice,>

Comments are closed.