Habilitación de OpenTelemetry en Azure Monitor para aplicaciones de .NET, Node.js y Python (versión preliminar)

El Exportador de OpenTelemetry en Azure Monitor es un componente que envía seguimientos y métricas (y, a la larga, toda la telemetría de la aplicación) a Application Insights de Azure Monitor. 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.

En este artículo se explica cómo habilitar y configurar la oferta en versión preliminar de OpenTelemetry en Azure Monitor. Cuando termine de leer las instrucciones de este artículo, podrá enviar seguimientos y métricas de OpenTelemetry a Application Insights de Azure Monitor.

Importante

La oferta de OpenTelemetry en Azure Monitor para aplicaciones de .NET, Node.js y Python se encuentra actualmente en versión preliminar. Consulte Términos de uso complementarios para las versiones preliminares de Microsoft Azure para conocer los términos legales que se aplican a las características de Azure que se encuentran en la versión beta, en versión preliminar o que todavía no se han publicado para que estén disponibles con carácter general.

Limitaciones de la versión preliminar

Reflexione sobre si esta versión preliminar satisface sus necesidades. Esta versión habilita el seguimiento distribuido, las métricas y excluye lo siguiente:

Si necesita una experiencia con todas las características, use el SDK existente de ASP.NET o ASP.NET Core de Application Insights hasta que la oferta de OpenTelemetry esté más madura.

Introducción

Siga los pasos de esta sección para instrumentar la aplicación con OpenTelemetry.

Requisitos previos

Instalación de las bibliotecas cliente

Instale el paquete NuGet Azure.Monitor.OpenTelemetry.Exporter más reciente:

dotnet add package --prerelease Azure.Monitor.OpenTelemetry.Exporter 

Si recibe un error como "No hay ninguna versión disponible del paquete "Azure.Monitor.OpenTelemetry.Exporter", probablemente se deba a que falta el valor de los orígenes del paquete NuGet. Pruebe a especificar el origen con la opción -s:

# Install the latest package with the NuGet package source specified.
dotnet add package --prerelease Azure.Monitor.OpenTelemetry.Exporter -s https://api.nuget.org/v3/index.json

Habilitación de Azure Monitor Application Insights

En esta sección se proporcionan instrucciones para habilitar OpenTelemetry.

Incorporación de código de instrumentación de OpenTelemetry

En el siguiente código se muestra cómo habilitar OpenTelemetry en una aplicación de consola de C# configurando OpenTelemetry TracerProvider. Este código debe estar en el inicio de la aplicación. En el caso de ASP.NET Core, suele realizarse en el método ConfigureServices de la clase Startup de la aplicación. En el caso de las aplicaciones ASP.NET, suele realizarse en Global.asax.cs.

using System.Diagnostics;
using Azure.Monitor.OpenTelemetry.Exporter;
using OpenTelemetry;
using OpenTelemetry.Trace;

public class Program
{
    private static readonly ActivitySource MyActivitySource = new ActivitySource(
        "OTel.AzureMonitor.Demo");

    public static void Main()
    {
        using var tracerProvider = Sdk.CreateTracerProviderBuilder()
            .AddSource("OTel.AzureMonitor.Demo")
            .AddAzureMonitorTraceExporter(o =>
            {
                o.ConnectionString = "<Your Connection String>";
            })
            .Build();

        using (var activity = MyActivitySource.StartActivity("TestActivity"))
        {
            activity?.SetTag("CustomTag1", "Value1");
            activity?.SetTag("CustomTag2", "Value2");
        }

        System.Console.WriteLine("Press Enter key to exit.");
        System.Console.ReadLine();
    }
}

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.

Sugerencia

Agregue bibliotecas de instrumentación para recopilar automáticamente datos de telemetría en marcos y bibliotecas populares.

Establecimiento de la cadena de conexión de Application Insights

Reemplace el marcador de posición <Your Connection String> del código anterior por la cadena de conexión de su recurso de Application Insights.

Captura de pantalla de la cadena de conexión de Application Insights

Confirmación de que los datos fluyen

Ejecute la aplicación y abra la pestaña Recurso de Application Insights en Azure Portal. Los datos pueden tardar unos minutos en aparecer en el portal.

Nota

Si no puede ejecutar la aplicación o no obtiene datos según lo esperado, consulte Solución de problemas.

Captura de pantalla de la pestaña

Importante

Si tiene dos o más servicios que emiten datos de telemetría al mismo recurso de Application Insights, es obligatorio establecer nombres de rol en la nube para representarlos correctamente en el mapa de aplicación.

Como parte del uso de la instrumentación de Application Insights, se recopilan y envían datos de diagnóstico a Microsoft. Estos datos ayudan a ejecutar y mejorar Application Insights. Puede deshabilitar la recopilación de datos no esenciales. Para obtener más información, consulte Statsbeat en Azure Application Insights.

Establecimiento del nombre y la instancia de rol en la nube

Puede establecer el nombre y la instancia de rol en la nube mediante los atributos de Recurso. Este paso actualiza los valores predeterminados del nombre y la instancia de rol en la nube a algo que tenga sentido para su equipo. Estos valores aparecerán en el mapa de aplicación como el nombre debajo de un nodo. El nombre de rol en la nube usa los atributos service.namespace y service.name, aunque recurre a service.name si no se establece service.namespace. Instancia de rol en la nube usa el valor del atributo service.instance.id.

// Setting role name and role instance
var resourceAttributes = new Dictionary<string, object> {
    { "service.name", "my-service" },
    { "service.namespace", "my-namespace" },
    { "service.instance.id", "my-instance" }};
var resourceBuilder = ResourceBuilder.CreateDefault().AddAttributes(resourceAttributes);
// Done setting role name and role instance

// Set ResourceBuilder on the provider.
var tracerProvider = Sdk.CreateTracerProviderBuilder()
    .SetResourceBuilder(resourceBuilder)
    .AddSource("OTel.AzureMonitor.Demo")
    .AddAzureMonitorTraceExporter(o =>
    {
        o.ConnectionString = "<Your Connection String>";
    })
    .Build();

Para obtener información sobre los atributos estándar de recursos, consulte Convenciones semánticas de recursos.

Habilitación del muestreo

Es posible que quiera habilitar el muestreo para reducir el volumen de ingesta de datos, lo que reduce el coste. Azure Monitor proporciona un muestreo personalizado de frecuencia fija que rellena los eventos con una "relación de muestreo", que Application Insights convierte en "ItemCount". El muestreo de frecuencia fija garantiza experiencias y recuentos de eventos precisos. El muestreo está diseñado para conservar los seguimientos entre servicios y es interoperable con SDK más antiguos de Application Insights. El muestreo espera una frecuencia de muestreo de entre 0 y 1 inclusive. Una tasa de 0,1 significa que se enviará aproximadamente el 10 % de los seguimientos. Para más información, consulte Más información sobre el muestreo.

Nota

Las métricas no se ven afectadas por el muestreo.

En este ejemplo se usa ApplicationInsightsSampler, que ofrece compatibilidad con los SDK de Application Insights.

dotnet add package --prerelease OpenTelemetry.Extensions.AzureMonitor
var tracerProvider = Sdk.CreateTracerProviderBuilder()
    .AddSource("OTel.AzureMonitor.Demo")
    .SetSampler(new ApplicationInsightsSampler(0.1F))
    .AddAzureMonitorTraceExporter(o =>
    {
     o.ConnectionString = "<Your Connection String>";
    })
    .Build();

Sugerencia

Si sabe dónde establecer la frecuencia de muestreo, comience en un 5 % (es decir, una relación de muestreo del 0,05) y ajústela en función de la precisión de las operaciones mostradas en las hojas de rendimiento y errores. Una tasa más alta suele dar como resultado una mayor precisión. Sin embargo, CUALQUIER muestreo afectará a la precisión, por lo que se recomienda alertar sobre las métricas de OpenTelemetry, que no se ven afectadas por el muestreo.

Bibliotecas de instrumentación

Las siguientes bibliotecas están validadas para funcionar con la versión preliminar.

Advertencia

Las bibliotecas de instrumentación se basan en especificaciones experimentales de OpenTelemetry. El compromiso de soporte técnico de la versión preliminar de Microsoft es garantizar que las siguientes bibliotecas emitan datos a Azure Monitor Application Insights, aunque es posible que los cambios importantes o la asignación experimental bloqueen algunos elementos de datos.

Seguimiento distribuido

Requests

Dependencias

(1) Admite informes automáticos (como SpanEvent) de excepciones no controladas

Métricas

Sugerencia

Las ofertas de OpenTelemetry emiten actualmente todas las métricas como Métricas personalizadas en el Explorador de métricas. Lo que establezca como nombre de medidor se convierte en el espacio de nombres de las métricas.

Modificación de la telemetría

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

Incorporación de atributos de intervalo

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

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.

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. Pueden seleccionar lo que deseen de él y almacenarlo como atributo.

Agregar una propiedad personalizada al seguimiento

Los atributos que se agregan a intervalos se exportan como propiedades personalizadas. Rellenan el campo customDimensions de las solicitudes o las tablas de dependencias de Application Insights.

  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 a continuación antes de Azure Monitor Exporter.

using var tracerProvider = Sdk.CreateTracerProviderBuilder()
        .AddSource("OTel.AzureMonitor.Demo")
        .AddProcessor(new ActivityEnrichingProcessor())
        .AddAzureMonitorTraceExporter(o =>
        {
                o.ConnectionString = "<Your Connection String>"
        })
        .Build();

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

using System.Diagnostics;
using OpenTelemetry;
using OpenTelemetry.Trace;

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

Para rellenar el campo client_IP de solicitudes, establezca el atributo http.client_ip 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 incorporación de propiedad personalizada, pero reemplace las siguientes líneas de código en ActivityEnrichingProcessor.cs:

// only applicable in case of activity.Kind == Server
activity.SetTag("http.client_ip", "<IP Address>");

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:

    using var tracerProvider = Sdk.CreateTracerProviderBuilder()
            .AddSource("OTel.AzureMonitor.Demo")
            .AddProcessor(new ActivityFilteringProcessor())
            .AddAzureMonitorTraceExporter(o =>
            {
                    o.ConnectionString = "<Your Connection String>"
            })
            .Build();
    

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

    using System.Diagnostics;
    using OpenTelemetry;
    using OpenTelemetry.Trace;
    
    public class ActivityFilteringProcessor : BaseProcessor<Activity>
    {
        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 exportará ninguna de las actividades creadas con ese origen.

Telemetría personalizada

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

Agregar Métricas personalizadas

Nota

Las Métricas personalizadas están en versión preliminar en Application Insights de Azure Monitor. Las métricas personalizadas sin dimensiones están disponibles de manera predeterminada. Para ver y alertar sobre las dimensiones, debe participar.

Es posible que quiera recopilar métricas más allá de lo que recopilan las bibliotecas de instrumentación.

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 Average
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 API anterior de métricas de seguimiento 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

using System.Diagnostics.Metrics;
using Azure.Monitor.OpenTelemetry.Exporter;
using OpenTelemetry;
using OpenTelemetry.Metrics;

public class Program
{
    private static readonly Meter meter = new("OTel.AzureMonitor.Demo");

    public static void Main()
    {
        using var meterProvider = Sdk.CreateMeterProviderBuilder()
            .AddMeter("OTel.AzureMonitor.Demo")
            .AddAzureMonitorMetricExporter(o =>
            {
                o.ConnectionString = "<Your Connection String>";
            })
            .Build();

        Histogram<long> myFruitSalePrice = meter.CreateHistogram<long>("FruitSalePrice");

        var rand = new Random();
        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"));

        System.Console.WriteLine("Press Enter key to exit.");
        System.Console.ReadLine();
    }
}

Ejemplo de contador

using System.Diagnostics.Metrics;
using Azure.Monitor.OpenTelemetry.Exporter;
using OpenTelemetry;
using OpenTelemetry.Metrics;

public class Program
{
    private static readonly Meter meter = new("OTel.AzureMonitor.Demo");

    public static void Main()
    {
        using var meterProvider = Sdk.CreateMeterProviderBuilder()
            .AddMeter("OTel.AzureMonitor.Demo")
            .AddAzureMonitorMetricExporter(o =>
            {
                o.ConnectionString = "<Your Connection String>";
            })
            .Build();

        Counter<long> myFruitCounter = meter.CreateCounter<long>("MyFruitCounter");

        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"));

        System.Console.WriteLine("Press Enter key to exit.");
        System.Console.ReadLine();
    }
}

Ejemplo de medidor

using System.Diagnostics.Metrics;
using Azure.Monitor.OpenTelemetry.Exporter;
using OpenTelemetry;
using OpenTelemetry.Metrics;

public class Program
{
    private static readonly Meter meter = new("OTel.AzureMonitor.Demo");

    public static void Main()
    {
        using var meterProvider = Sdk.CreateMeterProviderBuilder()
            .AddMeter("OTel.AzureMonitor.Demo")
            .AddAzureMonitorMetricExporter(o =>
            {
                o.ConnectionString = "<Your Connection String>";
            })
            .Build();

        var process = Process.GetCurrentProcess();
        
        ObservableGauge<int> myObservableGauge = meter.CreateObservableGauge("Thread.State", () => GetThreadState(process));

        System.Console.WriteLine("Press Enter key to exit.");
        System.Console.ReadLine();
    }
    
    private static IEnumerable<Measurement<int>> GetThreadState(Process process)
    {
        foreach (ProcessThread thread in process.Threads)
        {
            yield return new((int)thread.ThreadState, new("ProcessId", process.Id), new("ThreadId", thread.Id));
        }
    }
}

Agregar excepciones personalizadas

Seleccione bibliotecas de instrumentación que admitan automáticamente 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.

using (var activity = activitySource.StartActivity("ExceptionExample"))
{
    try
    {
        throw new Exception("Test exception");
    }
    catch (Exception ex)
    {
        activity?.SetStatus(ActivityStatusCode.Error);
        activity?.RecordException(ex);
    }
}

Habilitación del exportador de OTLP

Es posible que quiera habilitar el exportador de OpenTelemetry Protocol (OTLP) junto con Azure Monitor Exporter para enviar los datos de telemetría a dos ubicaciones.

Nota

El exportador de OTLP solo se muestra por comodidad. Oficialmente, no proporcionamos soporte técnico con relación al exportador de OTLP ni componentes o experiencias de terceros de nivel inferior. Se recomienda abrir una incidencia con OpenTelemetry-Collector en caso de problemas de OpenTelemetry que no sean del ámbito del Soporte técnico de Azure.

  1. Instale el paquete OpenTelemetry.Exporter.OpenTelemetryProtocol junto con Azure.Monitor.OpenTelemetry.Exporter en el proyecto.

  2. Agregue el siguiente fragmento de código. En este ejemplo se da por hecho que tiene un recopilador de OpenTelemetry con un receptor de OTLP en ejecución. Para obtener más información, consulte el ejemplo en GitHub.

    // Sends data to Application Insights as well as OTLP
    using var tracerProvider = Sdk.CreateTracerProviderBuilder()
            .AddSource("OTel.AzureMonitor.Demo")
            .AddAzureMonitorTraceExporter(o =>
            {
                o.ConnectionString = "<Your Connection String>"
            })
            .AddOtlpExporter()
            .Build();
    

Configuración

Almacenamiento sin conexión y reintentos automáticos

Para mejorar la confiabilidad y la resistencia, las ofertas basadas en OpenTelemetry de Azure Monitor escriben en un almacenamiento sin conexión o local de manera predeterminada cuando una aplicación pierde su conexión con Application Insights. Guarda la telemetría de la aplicación durante 48 horas y, periódicamente, intenta enviarla de nuevo. Además de superar el tiempo permitido, la telemetría se quitará ocasionalmente en aplicaciones de alta carga cuando se supere el tamaño máximo del archivo o el SDK no tenga la oportunidad de borrar el archivo. Si es necesario elegir, el producto guardará los eventos más recientes sobre los antiguos. En algunos casos, puede deshabilitar esta característica para optimizar el rendimiento de la aplicación. Más información

De manera predeterminada, AzureMonitorExporter usa una de las siguientes ubicaciones para el almacenamiento sin conexión (se muestra en orden de prioridad):

  • Windows
    • %LOCALAPPDATA%\Microsoft\AzureMonitor
    • %TEMP%\Microsoft\AzureMonitor
  • Distinta de Windows
    • %TMPDIR%/Microsoft/AzureMonitor
    • /var/tmp/Microsoft/AzureMonitor
    • /tmp/Microsoft/AzureMonitor

Para invalidar el directorio predeterminado, debe establecer AzureMonitorExporterOptions.StorageDirectory.

Por ejemplo:

var tracerProvider = Sdk.CreateTracerProviderBuilder()
    .AddAzureMonitorTraceExporter(o => {
        o.ConnectionString = "<Your Connection String>";
        o.StorageDirectory = "C:\\SomeDirectory";
    })
    .Build();

Para deshabilitar esta característica, debe establecer AzureMonitorExporterOptions.DisableOfflineStorage = true.

Solución de problemas

En esta sección se proporciona ayuda para solucionar problemas.

Activación del registro de diagnóstico

Azure Monitor Exporter usa EventSource para sus propios registros internos. Los registros del exportador están disponibles para cualquier elemento EventListener si se opta por el origen de nombre "OpenTelemetry-AzureMonitor-Exporter". En Solución de problemas de OpenTelemetry puede consultar los pasos para solucionar distintos problemas.

Problemas conocidos

Los problemas conocidos de Azure Monitor OpenTelemetry Exporter incluyen:

  • Falta el nombre de la operación en los datos de telemetría de dependencias, lo que afecta negativamente a la experiencia de la pestaña "Errores y rendimiento".
  • Falta el modelo de dispositivo en los datos de telemetría de solicitudes y dependencias, lo que afecta negativamente al análisis de cohortes de dispositivos.
  • El nombre del servidor de base de datos queda fuera del nombre de dependencia, lo que provoca que se agreguen incorrectamente tablas con el mismo nombre en diferentes servidores.

Prueba de la conectividad entre el host de la aplicación y el servicio de ingesta

Los SDK y agentes de Application Insights envían telemetría para ingerirse como llamadas REST a nuestros puntos de conexión de ingesta. Puede probar la conectividad desde el servidor web o la máquina host de la aplicación a los puntos de conexión del servicio de ingesta mediante clientes REST sin procesar con comandos de PowerShell o curl. Consulte Solución de problemas de telemetría de aplicaciones que faltan en Azure Monitor Application Insights.

Soporte técnico

Para obtener soporte técnico:

En caso de problemas de OpenTelemetry, póngase en contacto con la comunidad de .NET de OpenTelemetry directamente.

Comentarios de OpenTelemetry

Para proporcionar comentarios:

Pasos siguientes