Partilhar via


Adicionar e modificar o Azure Monitor OpenTelemetry para aplicativos .NET, Java, Node.js e Python

Este guia fornece instruções sobre como integrar e personalizar a instrumentação OpenTelemetry (OTel) no Azure Monitor Application Insights.

Para saber mais sobre os conceitos do OpenTelemetria, consulte a visão geral do OpenTelemetry ou as Perguntas frequentes do OpenTelemetry .

Nota

Para Aplicativos de Função do Azure, consulte Usar OpenTelemetry com o Azure Functions.

Recolha de dados automática

As distribuições coletam dados automaticamente integrando bibliotecas de instrumentação OpenTelemetry.

Bibliotecas de instrumentação incluídas

Pedidos

Dependências

Registo

  • ILogger

Para reduzir ou aumentar o número de logs enviados ao Azure Monitor, configure o log para definir o nível de log apropriado ou aplicar filtros. Por exemplo, você pode optar por enviar somente Warning e Error logs para o OpenTelemetry/Azure Monitor. O OpenTelemetry não controla o roteamento ou filtragem de logs - sua ILogger configuração toma essas decisões. Para obter mais informações sobre configurar ILogger, consulte Configurar registo.

Para obter mais informações sobre ILogger, consulte Registo de logs em C# e .NET e exemplos de código.

Notas de rodapé

  • ¹: Suporta a comunicação automática de exceções não tratadas/não detetadas
  • ²: Suporta métricas OpenTelemetry

Nota

As Distros OpenTelemetry do Azure Monitor incluem mapeamento e lógica personalizados para emitir automaticamente métricas padrão do Application Insights.

Gorjeta

Todas as métricas do OpenTelemetry coletadas automaticamente de bibliotecas de instrumentação ou manualmente coletadas de codificação personalizada são atualmente consideradas "métricas personalizadas" do Application Insights para fins de faturamento. Mais informações.

Adicionar uma biblioteca de instrumentação da comunidade

Você pode coletar mais dados automaticamente ao incluir bibliotecas de instrumentação da comunidade OpenTelemetry .

Atenção

Não apoiamos nem garantimos a qualidade das bibliotecas de instrumentação comunitárias. Para sugerir um para a nossa distro, publique ou vote na nossa comunidade de feedback. Esteja ciente de que algumas especificações do OpenTelemetry são experimentais e podem introduzir alterações significativas no futuro.

Para adicionar uma biblioteca da comunidade, use os ConfigureOpenTelemetryMeterProvider métodos ou ConfigureOpenTelemetryTracerProvider depois de adicionar o pacote NuGet para a biblioteca.

O exemplo a seguir demonstra como a Instrumentação de Tempo de Execução pode ser adicionada para coletar métricas extras:

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

Detetores de recursos

Os detetores de recursos descobrem metadados do ambiente na inicialização e preenchem atributos de recursos do OpenTelemetry como service.name, cloud.providere cloud.resource_id. Esses metadados potencializam experiências no Application Insights, como mapa de aplicativos e vinculação de computação, e melhoram a correlação entre rastreamentos, métricas e logs.

Gorjeta

Os atributos de recurso descrevem o processo e seu ambiente. Os atributos Span descrevem uma única operação. Use atributos de recurso para propriedades no nível do aplicativo, como service.name.

Ambientes suportados

Meio Ambiente Como funciona a deteção Observações
Serviço de Aplicações do Azure O SDK de idioma ou a distro do Azure Monitor lê variáveis de ambiente do Serviço de Aplicativo conhecidas e metadados de host Funciona com .NET, Java, Node.jse Python quando você usa as diretrizes neste artigo.
Funções do Azure Consulte o tutorial do Azure Functions OpenTelemetry Todas as orientações para funcionalidades do Azure Functions estão disponíveis lá.
Máquinas Virtuais do Azure O SDK de idioma ou distro consulta o Serviço de Metadados de Instância do Azure Verifique se a VM tem acesso ao ponto de extremidade do Serviço de Metadados de Instância.
Serviço Kubernetes do Azure (AKS) Use o processador OpenTelemetry Collector k8sattributes para adicionar metadados do Kubernetes Recomendado para todos os idiomas em execução no AKS.
Azure Container Apps Os detetores mapeiam variáveis de ambiente e identificadores de recursos quando disponíveis Você também pode definir OTEL_RESOURCE_ATTRIBUTES para preencher lacunas.

Instrumentação manual e automática

  • A instrumentação automática e as distribuições do Azure Monitor permitem a deteção de recursos quando executadas em ambientes do Azure onde há suporte.

  • Para configurações manuais, você pode definir atributos de recursos diretamente com as opções padrão do OpenTelemetry :

    # Applies to .NET (ASP.NET/ASP.NET Core), Java, Node.js, and Python
    export OTEL_SERVICE_NAME="my-service"
    export OTEL_RESOURCE_ATTRIBUTES="cloud.provider=azure,cloud.region=westus,cloud.resource_id=/subscriptions/<SUB>/resourceGroups/<RG>/providers/Microsoft.Web/sites/<APP>"
    

    No Windows PowerShell:

    $Env:OTEL_SERVICE_NAME="my-service"
    $Env:OTEL_RESOURCE_ATTRIBUTES="cloud.provider=azure,cloud.region=westus,cloud.resource_id=/subscriptions/<SUB>/resourceGroups/<RG>/providers/Microsoft.Web/sites/<APP>"
    

Considerações sobre ingestão de OTLP

  • O Application Insights usa service.name para derivar o nome da função de nuvem. Escolha um nome estável por serviço para evitar nós fragmentados no Mapa de Aplicativos.
  • cloud.resource_id melhora a vinculação de computação aos recursos do Azure. Se esse atributo estiver faltando, algumas experiências podem não mostrar o recurso do Azure que produziu os dados.

Coletar telemetria personalizada

Esta seção explica como coletar telemetria personalizada do seu aplicativo.

Dependendo do seu idioma e tipo de sinal, existem diferentes maneiras de coletar telemetria personalizada, incluindo:

  • OpenTelemetry API
  • Bibliotecas de logs/métricas adequadas para determinada língua
  • API clássica do Application Insights

Nota

A API de rastreamento do micrômetro para Java não é suportada.

A tabela a seguir representa os tipos de telemetria personalizada atualmente suportados:

Linguagem Eventos personalizados Métricas Personalizadas Dependências Exceções Visualizações de página Pedidos Rastreios
ASP.NET Núcleo
   OpenTelemetry API Sim Sim Sim Sim
    ILogger API (Interface de Programação de Aplicações) Sim
   API clássica AI
Java
   OpenTelemetry API Sim Sim Sim Sim
   Logback, Log4j, JUL Sim Sim
   Métricas do Micrometer Sim
   API clássica AI Sim Sim Sim Sim Sim Sim Sim
Node.js
   OpenTelemetry API Sim Sim Sim Sim
Píton
   OpenTelemetry API Sim Sim Sim Sim
   Módulo de registro em Python Sim
   Extensão de Eventos Sim Sim

Nota

O Application Insights Java 3.x e o Application Insights Node.js 3.x coletam telemetria da API do Application Insights Classic. Esse comportamento simplifica as atualizações e oferece suporte temporário à telemetria personalizada até que a API OpenTelemetry inclua todos os tipos de telemetria personalizada.

Adicionar métricas personalizadas

Nesse contexto, o termo métricas personalizadas refere-se à instrumentação manual do seu código para coletar métricas extras além do que as Bibliotecas de Instrumentação OpenTelemetry coletam automaticamente. Para saber mais sobre como usar métricas, consulte Métricas no Application Insights.

A API OpenTelemetry oferece seis "instrumentos" métricos para cobrir vários cenários métricos e você precisa escolher o "Tipo de agregação" correto ao visualizar métricas no Metrics Explorer. Esse requisito é verdadeiro ao usar a API de métrica OpenTelemetry para enviar métricas e ao usar uma biblioteca de instrumentação.

A tabela a seguir mostra os tipos de agregação recomendados para cada um dos OpenTelemetry Metric Instruments.

Instrumento OpenTelemetry Tipo de agregação do Azure Monitor
Contador Soma
Contador assíncrono Soma
Histograma Mín, Máx, Média, Soma e Contagem
Medidor assíncrono Média
UpDownCounter Soma
UpDownCounter assíncrono Soma

Atenção

Outros tipos de agregação não são significativos na maioria dos casos.

A Especificação OpenTelemetry descreve os instrumentos e fornece exemplos de quando se pode usar cada um.

Gorjeta

O histograma é o mais versátil e mais equivalente à API Classic GetMetric do Application Insights. Atualmente, o Azure Monitor transforma o instrumento de histograma nos cinco tipos de agregação suportados, e o desenvolvimento do suporte a percentis está em andamento. Embora menos versáteis, outros instrumentos OpenTelemetry têm um efeito menor no desempenho do seu aplicativo.

Exemplo de histograma

A inicialização da aplicação deve subscrever-se a um medidor pelo nome:

// 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();

O Meter deve ser inicializado usando o mesmo nome:

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

Contraexemplo

A inicialização da aplicação deve subscrever-se a um medidor pelo nome:

// 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();

O Meter deve ser inicializado usando o mesmo nome:

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

Exemplo de medidor

A inicialização da aplicação deve subscrever-se a um medidor pelo nome:

// 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();

O Meter deve ser inicializado usando o mesmo nome:

// 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));
    }
}

Adicionar exceções personalizadas

Selecione bibliotecas de instrumentação que reportam automaticamente exceções ao Application Insights. No entanto, pode querer reportar manualmente exceções para além do que as bibliotecas de instrumentação reportam. Por exemplo, as exceções detetadas pelo seu código normalmente não são relatadas. Você pode relatá-los para chamar a atenção em experiências relevantes, incluindo a seção de falhas e visualizações de transações de ponta a ponta.

  • Para registrar uma exceção usando uma atividade:

    // 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 uma exceção usando 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" });
    }
    

Adicionar intervalos personalizados

Talvez possas querer adicionar um intervalo personalizado em dois cenários. Primeiro, quando há uma solicitação de dependência ainda não coletada por uma biblioteca de instrumentação. Em segundo lugar, quando se deseja modelar um processo de aplicação como um intervalo na visualização de uma transação completa.

Nota

As Activity classes e ActivitySource do System.Diagnostics namespace representam os conceitos OpenTelemetry de Span e Tracer, respectivamente. Você cria ActivitySource diretamente usando seu construtor em vez de usar TracerProvider. Cada ActivitySource classe deve ser explicitamente conectada a TracerProvider usando AddSource(). Isso ocorre porque partes da API de rastreamento OpenTelemetry são incorporadas diretamente ao tempo de execução do .NET. Para saber mais, consulte Introdução à API de rastreamento do OpenTelemetry .NET.

// 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 define-se por padrão como ActivityKind.Internal, mas podes fornecer qualquer outro ActivityKind. ActivityKind.Client, ActivityKind.Producere ActivityKind.Internal são mapeados para o Application Insights dependencies. ActivityKind.Server e ActivityKind.Consumer são mapeados para o Application Insights requests.

Enviar eventos personalizados

O Application Insights armazena customEvents eventos personalizados na tabela. Uma maneira de analisá-los, filtrá-los e visualizá-los é usando as experiências de uso do Application Insights.

Se quiser automatizar a coleção de eventos de interação do lado do cliente, você pode usar o plug-in no JavaScript SDK.

Os eventos personalizados estão na Pré-visualização Pública e utilizam Azure.Monitor.OpenTelemetry.AspNetCore 1.3.0-beta.3.

Importante

Consulte os Termos de Utilização Complementares das Visualizações Prévias do Microsoft Azure para obter os termos legais que se aplicam às funcionalidades do Azure que estão em beta, em pré-visualização ou que ainda não foram lançadas para disponibilidade geral.

Para enviar um CustomEvent usando ILogger, defina o "microsoft.custom_event.name" atributo no modelo de mensagem.

// Create a logger factory and configure OpenTelemetry with Azure Monitor
var loggerFactory = LoggerFactory.Create(builder =>
{
    builder
        .AddOpenTelemetry(options =>
        {
            options.AddAzureMonitorLogExporter();
        });
});

// Create a logger for the specified category
var logger = loggerFactory.CreateLogger(logCategoryName);

// Log a custom event with a custom name and additional attribute
// The 'microsoft.custom_event.name' value will be used as the name of the customEvent
logger.LogInformation("{microsoft.custom_event.name} {additional_attrs}", "test-event-name", "val1");

Modificar telemetria

Esta seção explica como modificar a telemetria.

Adicionar atributos span

Esses atributos podem incluir a adição de uma propriedade personalizada à sua telemetria. Você também pode usar atributos para definir campos opcionais no esquema do Application Insights, como IP do cliente.

Adicionar uma propriedade personalizada a um Span

Todos os atributos adicionados às extensões são exportados como propriedades personalizadas. Eles preenchem o campo customDimensions na tabela de solicitações, dependências, rastreamentos ou exceções.

Para adicionar atributos span, use uma das duas maneiras a seguir:

  • Use as opções fornecidas pelas bibliotecas de instrumentação.
  • Adicione um processador span personalizado.

Gorjeta

A vantagem de usar as opções fornecidas pelas bibliotecas de instrumentação, quando estão disponíveis, é que todo o contexto está disponível. Como resultado, os usuários podem optar por adicionar ou filtrar mais atributos. Por exemplo, a opção enrich na biblioteca de instrumentação HttpClient dá aos usuários acesso ao HttpRequestMessage e ao próprio HttpResponseMessage. Eles podem selecionar qualquer coisa dele e armazená-lo como um atributo.

  1. Muitas bibliotecas de instrumentação oferecem uma opção enriquecedora. Para obter orientação, consulte os arquivos readme de bibliotecas de instrumentação individuais:

  2. Use um processador personalizado:

    Gorjeta

    Adicione o processador mostrado aqui antes de adicionar o 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();
    

    Adicione ActivityEnrichingProcessor.cs ao seu projeto com o seguinte 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");
        }
    }
    

Definir o IP do usuário

Você pode preencher o campo client_IP para solicitações definindo um atributo na extensão. O Application Insights usa o endereço IP para gerar atributos de localização do usuário e, em seguida, descarta-o por padrão.

Use o exemplo de propriedade personalizada, mas substitua as seguintes linhas de código em 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>");

Definir o ID de usuário ou o ID de usuário autenticado

Você pode preencher o campo user_Id ou user_AuthenticatedId para solicitações usando as diretrizes a seguir. O ID de utilizador é um identificador de utilizador anónimo. ID de usuário autenticado é um identificador de usuário conhecido.

Importante

Consulte as leis de privacidade aplicáveis antes de definir o ID de Usuário Autenticado.

Use o exemplo de propriedade 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>");

Adicionar atributos de log

OpenTelemetry usa . NET's ILogger. A anexação de dimensões personalizadas aos logs pode ser realizada usando um modelo de mensagem.

Obter o trace ID ou span ID

Você pode obter o Trace ID e Span ID do Span atualmente ativo usando as etapas a seguir.

Nota

As Activity classes e ActivitySource do System.Diagnostics namespace representam os conceitos OpenTelemetry de Span e Tracer, respectivamente. Isso ocorre porque partes da API de rastreamento OpenTelemetry são incorporadas diretamente ao tempo de execução do .NET. Para saber mais, consulte Introdução à API de rastreamento do OpenTelemetry .NET.

// 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();

Próximos passos