Agregar, modificar y filtrar OpenTelemetry

En este artículo se proporcionan instrucciones sobre cómo agregar, modificar y filtrar OpenTelemetry para aplicaciones mediante Azure Monitor Application Insights.

Para obtener más información sobre conceptos de OpenTelemetry, consulte Introducción a OpenTelemetry o las preguntas más frecuentes sobre el estándar.

Recopilación automática de datos

Las distribuciones recopilan automáticamente los datos mediante la inclusión de bibliotecas de instrumentación de OpenTelemetry.

Bibliotecas de instrumentación incluidas

Solicitudes

Dependencias

Registro

  • ILogger

Para obtener más información acerca de ILogger, consulte Inicio de sesión en C# y .NET y ejemplos de código.

Notas al pie

  • ¹: Admite informes automáticos de excepciones no controladas/no detectadas
  • ²: Admite métricas de OpenTelemetry
  • ³: De manera predeterminada, el registro solo se recopila en el nivel INFO o superior. Para cambiar esta configuración, vea las opciones de configuración.
  • ⁴: De manera predeterminada, el registro solo se recopila cuando dicho registro se realiza en el nivel de ADVERTENCIA o superior.

Nota:

Las Distribuciones de OpenTelemetry de Azure Monitor incluyen la asignación personalizada y la lógica para emitir automáticamente métricas estándar de Application Insights.

Sugerencia

Todas las métricas de OpenTelemetry si se recopilan automáticamente de bibliotecas de instrumentación o se recopilan manualmente de codificación personalizada se consideran actualmente "métricas personalizadas" de Application Insights con fines de facturación. Más información.

Adición de una biblioteca de instrumentación de la comunidad

Puede recopilar más datos automáticamente al incluir bibliotecas de instrumentación de la comunidad de OpenTelemetry.

Precaución

No se admite ni garantiza la calidad de las bibliotecas de instrumentación de la comunidad. Para sugerir una para nuestra distribución, publique o vote en nuestra comunidad de comentarios. Tenga en cuenta que algunos se basan en especificaciones de OpenTelemetry experimentales y pueden introducir cambios importantes en el futuro.

Para agregar una biblioteca de la comunidad, use los métodos ConfigureOpenTelemetryMeterProvider o ConfigureOpenTelemetryTracerProvider después de agregar el paquete NuGet de la biblioteca.

En el ejemplo siguiente se muestra cómo se puede agregar la instrumentación en tiempo de ejecución para recopilar métricas adicionales:

dotnet add package OpenTelemetry.Instrumentation.Runtime 
// Create a new ASP.NET Core web application builder.
var builder = WebApplication.CreateBuilder(args);

// Configure the OpenTelemetry meter provider to add runtime instrumentation.
builder.Services.ConfigureOpenTelemetryMeterProvider((sp, builder) => builder.AddRuntimeInstrumentation());

// Add the Azure Monitor telemetry service to the application.
// This service will collect and send telemetry data to Azure Monitor.
builder.Services.AddOpenTelemetry().UseAzureMonitor();

// Build the ASP.NET Core web application.
var app = builder.Build();

// Start the ASP.NET Core web application.
app.Run();

Recopilación de telemetría personalizada

En esta sección se explica cómo recopilar datos de telemetría personalizados de la aplicación.

Según el idioma y el tipo de señal, hay diferentes maneras de recopilar telemetría personalizada, entre las que se incluyen:

  • OpenTelemetry API
  • Bibliotecas de métricas o registro específicas del idioma
  • Classic API de Application Insights

En la tabla siguiente, se representan los tipos de telemetría personalizados admitidos actualmente:

Lenguaje Eventos personalizados Métricas personalizadas Dependencias Excepciones Vistas de página Requests Traces
ASP.NET Core
   OpenTelemetry API
   ILogger API
   Classic API de IA
Java
   OpenTelemetry API
   Logback, Log4j, JUL
   Micrometer Metrics
   Classic API de IA
Node.js
   OpenTelemetry API
Python
   OpenTelemetry API
   Módulo de registro de Python
   Extensión de eventos

Nota

Application Insights para Java 3.x escucha la telemetría que se envía a Classic API de Application Insights. De forma similar, Node.js 3.x de Application Insights recopila eventos creados con Classic API de Application Insights. Esto facilita la actualización y rellena una brecha importante en nuestra compatibilidad con telemetría personalizada hasta que se admiten todos los tipos de telemetría personalizados a través de la API de OpenTelemetry.

Adición de métricas personalizadas

En este contexto, el término de métricas personalizadas hace referencia a instrumentar manualmente el código para recopilar métricas adicionales más allá de lo que recopilan automáticamente las bibliotecas de instrumentación de OpenTelemetry.

La API de OpenTelemetry ofrece seis "instrumentos" de métricas para cubrir varios escenarios de métricas, y tendrá que elegir el "Tipo de agregación" correcto al visualizar las métricas en el Explorador de métricas. Este requisito es cierto cuando se usa la API de métricas de OpenTelemetry para enviar métricas y cuando se usa una biblioteca de instrumentación.

En la tabla siguiente se muestran los tipos de agregación recomendados para cada uno de los instrumentos de métricas de OpenTelemetry.

Instrumento de OpenTelemetry Tipo de agregación en Azure Monitor
Contador Sum
Contador asincrónico Sum
Histograma Min, Max, Average, Sum y Count
Medidor asincrónico Media
UpDownCounter Sum
UpDownCounter asincrónico Sum

Precaución

Los tipos de agregación, más allá de lo que se muestra en la tabla, no suelen ser significativos.

La especificación de OpenTelemetry describe los instrumentos y proporciona ejemplos de cuándo puede usar cada uno de ellos.

Sugerencia

El histograma es el equivalente más versátil y más cercano a la Classic API de GetMetric de Application Insights. Actualmente, Azure Monitor aplana el instrumento de histograma en nuestros cinco tipos de agregación admitidos; estamos trabajando en añadir la compatibilidad con los percentiles. Aunque es menos versátil, otros instrumentos de OpenTelemetry tienen un menor impacto en el rendimiento de la aplicación.

Ejemplo de histograma

El inicio de la aplicación debe suscribirse a un Medidor por nombre:

// Create a new ASP.NET Core web application builder.
var builder = WebApplication.CreateBuilder(args);

// Configure the OpenTelemetry meter provider to add a meter named "OTel.AzureMonitor.Demo".
builder.Services.ConfigureOpenTelemetryMeterProvider((sp, builder) => builder.AddMeter("OTel.AzureMonitor.Demo"));

// Add the Azure Monitor telemetry service to the application.
// This service will collect and send telemetry data to Azure Monitor.
builder.Services.AddOpenTelemetry().UseAzureMonitor();

// Build the ASP.NET Core web application.
var app = builder.Build();

// Start the ASP.NET Core web application.
app.Run();

El Meter debe inicializarse usando ese mismo nombre:

// Create a new meter named "OTel.AzureMonitor.Demo".
var meter = new Meter("OTel.AzureMonitor.Demo");

// Create a new histogram metric named "FruitSalePrice".
Histogram<long> myFruitSalePrice = meter.CreateHistogram<long>("FruitSalePrice");

// Create a new Random object.
var rand = new Random();

// Record a few random sale prices for apples and lemons, with different colors.
myFruitSalePrice.Record(rand.Next(1, 1000), new("name", "apple"), new("color", "red"));
myFruitSalePrice.Record(rand.Next(1, 1000), new("name", "lemon"), new("color", "yellow"));
myFruitSalePrice.Record(rand.Next(1, 1000), new("name", "lemon"), new("color", "yellow"));
myFruitSalePrice.Record(rand.Next(1, 1000), new("name", "apple"), new("color", "green"));
myFruitSalePrice.Record(rand.Next(1, 1000), new("name", "apple"), new("color", "red"));
myFruitSalePrice.Record(rand.Next(1, 1000), new("name", "lemon"), new("color", "yellow"));

Ejemplo de contador

El inicio de la aplicación debe suscribirse a un Medidor por nombre:

// Create a new ASP.NET Core web application builder.
var builder = WebApplication.CreateBuilder(args);

// Configure the OpenTelemetry meter provider to add a meter named "OTel.AzureMonitor.Demo".
builder.Services.ConfigureOpenTelemetryMeterProvider((sp, builder) => builder.AddMeter("OTel.AzureMonitor.Demo"));

// Add the Azure Monitor telemetry service to the application.
// This service will collect and send telemetry data to Azure Monitor.
builder.Services.AddOpenTelemetry().UseAzureMonitor();

// Build the ASP.NET Core web application.
var app = builder.Build();

// Start the ASP.NET Core web application.
app.Run();

El Meter debe inicializarse usando ese mismo nombre:

// Create a new meter named "OTel.AzureMonitor.Demo".
var meter = new Meter("OTel.AzureMonitor.Demo");

// Create a new counter metric named "MyFruitCounter".
Counter<long> myFruitCounter = meter.CreateCounter<long>("MyFruitCounter");

// Record the number of fruits sold, grouped by name and color.
myFruitCounter.Add(1, new("name", "apple"), new("color", "red"));
myFruitCounter.Add(2, new("name", "lemon"), new("color", "yellow"));
myFruitCounter.Add(1, new("name", "lemon"), new("color", "yellow"));
myFruitCounter.Add(2, new("name", "apple"), new("color", "green"));
myFruitCounter.Add(5, new("name", "apple"), new("color", "red"));
myFruitCounter.Add(4, new("name", "lemon"), new("color", "yellow"));

Ejemplo de medidor

El inicio de la aplicación debe suscribirse a un Medidor por nombre:

// Create a new ASP.NET Core web application builder.
var builder = WebApplication.CreateBuilder(args);

// Configure the OpenTelemetry meter provider to add a meter named "OTel.AzureMonitor.Demo".
builder.Services.ConfigureOpenTelemetryMeterProvider((sp, builder) => builder.AddMeter("OTel.AzureMonitor.Demo"));

// Add the Azure Monitor telemetry service to the application.
// This service will collect and send telemetry data to Azure Monitor.
builder.Services.AddOpenTelemetry().UseAzureMonitor();

// Build the ASP.NET Core web application.
var app = builder.Build();

// Start the ASP.NET Core web application.
app.Run();

El Meter debe inicializarse usando ese mismo nombre:

// Get the current process.
var process = Process.GetCurrentProcess();

// Create a new meter named "OTel.AzureMonitor.Demo".
var meter = new Meter("OTel.AzureMonitor.Demo");

// Create a new observable gauge metric named "Thread.State".
// This metric will track the state of each thread in the current process.
ObservableGauge<int> myObservableGauge = meter.CreateObservableGauge("Thread.State", () => GetThreadState(process));

private static IEnumerable<Measurement<int>> GetThreadState(Process process)
{
    // Iterate over all threads in the current process.
    foreach (ProcessThread thread in process.Threads)
    {
        // Create a measurement for each thread, including the thread state, process ID, and thread ID.
        yield return new((int)thread.ThreadState, new("ProcessId", process.Id), new("ThreadId", thread.Id));
    }
}

Agregar excepciones personalizadas

Seleccione bibliotecas de instrumentación que informen automáticamente de excepciones en Application Insights. Sin embargo, es posible que desee notificar algunas excepciones manualmente, más allá de lo que aparece en el informe de bibliotecas de instrumentación. Por ejemplo, las excepciones detectadas por el código normalmente no se notifican. Es posible que desee que se notifiquen para tenerlas en cuenta en experiencias pertinentes, incluida la sección de errores y las vistas de transacciones de un extremo a otro.

  • Para registrar una excepción mediante una actividad:

    // Start a new activity named "ExceptionExample".
    using (var activity = activitySource.StartActivity("ExceptionExample"))
    {
        // Try to execute some code.
        try
        {
            throw new Exception("Test exception");
        }
        // If an exception is thrown, catch it and set the activity status to "Error".
        catch (Exception ex)
        {
            activity?.SetStatus(ActivityStatusCode.Error);
            activity?.RecordException(ex);
        }
    }
    
  • Para registrar una excepción mediante ILogger:

    // Create a logger using the logger factory. The logger category name is used to filter and route log messages.
    var logger = loggerFactory.CreateLogger(logCategoryName);
    
    // Try to execute some code.
    try
    {
        throw new Exception("Test Exception");
    }
    catch (Exception ex)
    {
        // Log an error message with the exception. The log level is set to "Error" and the event ID is set to 0.
        // The log message includes a template and a parameter. The template will be replaced with the value of the parameter when the log message is written.
        logger.Log(
            logLevel: LogLevel.Error,
            eventId: 0,
            exception: ex,
            message: "Hello {name}.",
            args: new object[] { "World" });
    }
    

Agregar intervalos personalizados

Puede que quiera agregar un intervalo personalizado en dos escenarios. En primer lugar, cuando hay una solicitud de dependencia no recopilada por una biblioteca de instrumentación. En segundo lugar, cuando quiere modelar un proceso de aplicación como un intervalo en la vista de transacciones de un extremo a otro.

Nota

Las clases Activity y ActivitySource del espacio de nombres System.Diagnostics representan respectivamente los conceptos de Span y Tracer de OpenTelemetry. Para crear ActivitySource directamente, use su constructor en lugar de TracerProvider. Cada clase ActivitySource debe estar conectada explícitamente a TracerProvider mediante AddSource(). El motivo es que algunas partes de la API de seguimiento de OpenTelemetry se incorporan directamente al runtime de .NET. Para más información, vea Introducción a la API de seguimiento de .NET OpenTelemetry.

// Define an activity source named "ActivitySourceName". This activity source will be used to create activities for all requests to the application.
internal static readonly ActivitySource activitySource = new("ActivitySourceName");

// Create an ASP.NET Core application builder.
var builder = WebApplication.CreateBuilder(args);

// Configure the OpenTelemetry tracer provider to add a source named "ActivitySourceName". This will ensure that all activities created by the activity source are traced.
builder.Services.ConfigureOpenTelemetryTracerProvider((sp, builder) => builder.AddSource("ActivitySourceName"));

// Add the Azure Monitor telemetry service to the application. This service will collect and send telemetry data to Azure Monitor.
builder.Services.AddOpenTelemetry().UseAzureMonitor();

// Build the ASP.NET Core application.
var app = builder.Build();

// Map a GET request to the root path ("/") to the specified action.
app.MapGet("/", () =>
{
    // Start a new activity named "CustomActivity". This activity will be traced and the trace data will be sent to Azure Monitor.
    using (var activity = activitySource.StartActivity("CustomActivity"))
    {
        // your code here
    }

    // Return a response message.
    return $"Hello World!";
});

// Start the ASP.NET Core application.
app.Run();

StartActivity de forma predeterminada es ActivityKind.Internal, pero puede proporcionar cualquier otro ActivityKind. ActivityKind.Client, ActivityKind.Producer y ActivityKind.Internal se asignan a Application Insights dependencies. ActivityKind.Server y ActivityKind.Consumer se asignan a Application Insights requests.

Envío de telemetría personalizada mediante Classic API de Application Insights

Se recomienda usar las API de OpenTelemetry siempre que sea posible, pero puede haber algunos escenarios en los que tenga que usar la Classic API de Application Insights.

Eventos

  1. Agregue Microsoft.ApplicationInsights a la aplicación.

  2. Cree una instancia TelemetryClient.

    Nota:

    Es importante crear solo una instancia de TelemetryClient por aplicación.

    var telemetryConfiguration = new TelemetryConfiguration { ConnectionString = "" };
    var telemetryClient = new TelemetryClient(telemetryConfiguration);
    
  3. Use el cliente para enviar telemetría personalizada:

    telemetryClient.TrackEvent("testEvent");
    

Modificación de la telemetría

En esta sección se explica cómo modificar la telemetría.

Incorporación de atributos de intervalo

Estos atributos pueden incluir agregar una propiedad personalizada a sus datos de telemetría. También puede usar atributos para establecer campos opcionales en el esquema de Application Insights, como la IP de cliente.

Adición de una propiedad personalizada a un intervalo

Los atributos que se agregan a intervalos se exportan como propiedades personalizadas. Se rellena el campo customDimensions de la tabla de solicitudes, dependencias, seguimientos o excepciones.

Puede agregar atributos de intervalo mediante cualquiera de los dos métodos siguientes:

Sugerencia

La ventaja de usar las opciones proporcionadas por las bibliotecas de instrumentación, cuando están disponibles, es que se dispone de todo el contexto. En consecuencia, los usuarios pueden optar por agregar o filtrar más atributos. Por ejemplo, la opción de enriquecimiento de la biblioteca de instrumentación HttpClient proporciona a los usuarios acceso al propio HttpRequestMessage y HttpResponseMessage. Pueden seleccionar lo que deseen de él y almacenarlo como atributo.

  1. Muchas bibliotecas de instrumentación proporcionan una opción de enriquecimiento. Para obtener instrucciones, consulte el archivo Léame de cada biblioteca de instrumentación:

  2. Use un procesador personalizado:

    Sugerencia

    Agregue el procesador que se muestra aquí antes de agregar Azure Monitor.

    // Create an ASP.NET Core application builder.
    var builder = WebApplication.CreateBuilder(args);
    
    // Configure the OpenTelemetry tracer provider to add a new processor named ActivityEnrichingProcessor.
    builder.Services.ConfigureOpenTelemetryTracerProvider((sp, builder) => builder.AddProcessor(new ActivityEnrichingProcessor()));
    
    // Add the Azure Monitor telemetry service to the application. This service will collect and send telemetry data to Azure Monitor.
    builder.Services.AddOpenTelemetry().UseAzureMonitor();
    
    // Build the ASP.NET Core application.
    var app = builder.Build();
    
    // Start the ASP.NET Core application.
    app.Run();
    

    Agregue ActivityEnrichingProcessor.cs al proyecto con el siguiente código:

    public class ActivityEnrichingProcessor : BaseProcessor<Activity>
    {
        public override void OnEnd(Activity activity)
        {
            // The updated activity will be available to all processors which are called after this processor.
            activity.DisplayName = "Updated-" + activity.DisplayName;
            activity.SetTag("CustomDimension1", "Value1");
            activity.SetTag("CustomDimension2", "Value2");
        }
    }
    

Establecimiento de la IP de usuario

Puede rellenar el campo client_IP para solicitudes, estableciendo un atributo en el intervalo. Application Insights usa la dirección IP para generar atributos de ubicación del usuario y luego la descarta de manera predeterminada.

Use el ejemplo de propiedad personalizada, pero reemplace las siguientes líneas de código en ActivityEnrichingProcessor.cs:

// Add the client IP address to the activity as a tag.
// only applicable in case of activity.Kind == Server
activity.SetTag("client.address", "<IP Address>");

Establecimiento del identificador de usuario o el identificador de usuario autenticado

Puede rellenar el campo user_Id o user_AuthenticatedId para las solicitudes mediante las instrucciones siguientes. El identificador de usuario es un identificador de usuario anónimo. El identificador de usuario autenticado es un identificador de usuario conocido.

Importante

Consulte las leyes de privacidad aplicables antes de establecer el id. de usuario autenticado.

Use el ejemplo de propiedad personalizada:

// Add the user ID to the activity as a tag, but only if the activity is not null.
activity?.SetTag("enduser.id", "<User Id>");

Agregar atributos de registro

OpenTelemetry usa ILogger de .NET. La asociación de dimensiones personalizadas a los registros se puede realizar mediante una plantilla de mensaje.

Telemetría de filtro

Use los siguientes métodos para filtrar los datos de telemetría antes de que salgan de la aplicación.

  1. Muchas bibliotecas de instrumentación proporcionan una opción de filtrado. Para obtener instrucciones, consulte el archivo Léame de cada biblioteca de instrumentación:

  2. Use un procesador personalizado:

    Sugerencia

    Agregue el procesador que se muestra aquí antes de agregar Azure Monitor.

    // Create an ASP.NET Core application builder.
    var builder = WebApplication.CreateBuilder(args);
    
    // Configure the OpenTelemetry tracer provider to add a new processor named ActivityFilteringProcessor.
    builder.Services.ConfigureOpenTelemetryTracerProvider((sp, builder) => builder.AddProcessor(new ActivityFilteringProcessor()));
    // Configure the OpenTelemetry tracer provider to add a new source named "ActivitySourceName".
    builder.Services.ConfigureOpenTelemetryTracerProvider((sp, builder) => builder.AddSource("ActivitySourceName"));
    // Add the Azure Monitor telemetry service to the application. This service will collect and send telemetry data to Azure Monitor.
    builder.Services.AddOpenTelemetry().UseAzureMonitor();
    
    // Build the ASP.NET Core application.
    var app = builder.Build();
    
    // Start the ASP.NET Core application.
    app.Run();
    

    Agregue ActivityFilteringProcessor.cs al proyecto con el siguiente código:

    public class ActivityFilteringProcessor : BaseProcessor<Activity>
    {
        // The OnStart method is called when an activity is started. This is the ideal place to filter activities.
        public override void OnStart(Activity activity)
        {
            // prevents all exporters from exporting internal activities
            if (activity.Kind == ActivityKind.Internal)
            {
                activity.IsAllDataRequested = false;
            }
        }
    }
    
  3. Si un determinado origen no se agrega de manera explícita mediante AddSource("ActivitySourceName"), no se exporta ninguna de las actividades creadas con ese origen.

Obtención del identificador de seguimiento o el de intervalo

Puede obtener el Trace ID y Span ID del intervalo activo actualmente mediante los siguientes pasos.

Nota

Las clases Activity y ActivitySource del espacio de nombres System.Diagnostics representan respectivamente los conceptos de Span y Tracer de OpenTelemetry. El motivo es que algunas partes de la API de seguimiento de OpenTelemetry se incorporan directamente al runtime de .NET. Para más información, vea Introducción a la API de seguimiento de .NET OpenTelemetry.

// Get the current activity.
Activity activity = Activity.Current;
// Get the trace ID of the activity.
string traceId = activity?.TraceId.ToHexString();
// Get the span ID of the activity.
string spanId = activity?.SpanId.ToHexString();

Pasos siguientes