Usar o OpenTelemetry com o OTLP e o Aspire Painel

Este artigo mostra como instrumentar uma API Web do .NET com o OpenTelemetry e enviar seus logs, métricas e rastreamentos para o painel Aspire usando OTLP. Adicione os pacotes OpenTelemetry, configure métricas e rastreamentos personalizados e exiba os resultados no painel.

O Aspire Dashboard é uma parte padrão de Aspire, mas também está disponível como um contêiner Docker independente que fornece um endpoint OTLP para envio de telemetria. O painel exibe logs, métricas e rastros. Usar o painel dessa forma não tem dependência de Aspire e permite visualizar a telemetria de qualquer aplicativo que envia telemetria por meio de OTLP. Ele funciona igualmente bem para aplicativos escritos em Java, Go ou Python, desde que possam enviar sua telemetria para um ponto de extremidade OTLP.

O Aspire Dashboard requer menos configuração e menos etapas de instalação do que soluções de código aberto, como Prometheus, Grafana e Jaeger. Mas, ao contrário dessas ferramentas, o Aspire Painel é uma ferramenta de visualização do desenvolvedor, não uma ferramenta de monitoramento de produção.

1. Criar o projeto

Crie um projeto simples de API Web usando o modelo ASP.NET Core Vazio no Visual Studio ou o seguinte comando da CLI do .NET:

dotnet new web

2. Faça referência aos pacotes OpenTelemetry

Para adicionar os pacotes OpenTelemetry, use o Gerenciador de Pacotes do NuGet ou execute os seguintes dotnet add package comandos:

dotnet add package OpenTelemetry.Exporter.OpenTelemetryProtocol
dotnet add package OpenTelemetry.Extensions.Hosting
dotnet add package OpenTelemetry.Instrumentation.AspNetCore
dotnet add package OpenTelemetry.Instrumentation.Http

Como alternativa, adicione os seguintes PackageReference itens diretamente ao arquivo de projeto:

<ItemGroup>
  <PackageReference Include="OpenTelemetry.Exporter.OpenTelemetryProtocol" Version="1.17.0" />
  <PackageReference Include="OpenTelemetry.Extensions.Hosting" Version="1.17.0" />
  <PackageReference Include="OpenTelemetry.Instrumentation.AspNetCore" Version="1.17.0" />
  <PackageReference Include="OpenTelemetry.Instrumentation.Http" Version="1.17.0" />
</ItemGroup>

Observação

Como as APIs OTel estão em constante evolução, use as versões mais recentes.

3. Adicionar usando diretivas

Adicione as seguintes using diretivas à parte superior do arquivo:

using System.Diagnostics;
using System.Diagnostics.Metrics;
using OpenTelemetry.Exporter;
using OpenTelemetry.Logs;
using OpenTelemetry.Metrics;
using OpenTelemetry.Resources;
using OpenTelemetry.Trace;

4. Adicionar métricas e definições de atividade

O código a seguir define uma nova métrica (greetings.count) que conta quantas vezes um cliente chama a API e uma nova fonte de atividade (Otel.Example). Insira este código antes builder.Build:

// Custom metrics for the application
var greeterMeter = new Meter("OTel.Example", "1.0.0");
var countGreetings = greeterMeter.CreateCounter<int>("greetings.count", description: "Counts the number of greetings");

// Custom ActivitySource for the application
var greeterActivitySource = new ActivitySource("OTel.Example");

5. Configurar o OpenTelemetry com os provedores corretos

Inserir o seguinte código antes de builder.Build:

// Configure the shared OTLP connection used by logs, metrics, and traces.
var otlpEndpoint = new Uri(builder.Configuration["OTEL_EXPORTER_OTLP_ENDPOINT"]!);
Action<OtlpExporterOptions> configureOtlp = options =>
{
    options.Endpoint = otlpEndpoint;
    options.Protocol = OtlpExportProtocol.Grpc;
    options.Headers = builder.Configuration["OTEL_EXPORTER_OTLP_HEADERS"]; // To secure endpoint (not in this example)
};

// Setup logging to be exported via OpenTelemetry
builder.Logging.AddOpenTelemetry(logging =>
{
    logging.IncludeFormattedMessage = true;
    logging.IncludeScopes = true;
    logging.AddOtlpExporter(configureOtlp);
});

var otel = builder.Services.AddOpenTelemetry();

// Identify this application as a single service in the Aspire dashboard.
otel.ConfigureResource(resource => resource.AddService(builder.Configuration["OTEL_SERVICE_NAME"]!));

// Add Metrics for ASP.NET Core and our custom metrics and export via OTLP
otel.WithMetrics(metrics =>
{
    // Metrics provider from OpenTelemetry
    metrics.AddAspNetCoreInstrumentation();

    // Our custom metrics
    metrics.AddMeter(greeterMeter.Name);

    // Metrics provided by ASP.NET Core in .NET
    metrics.AddMeter("Microsoft.AspNetCore.Hosting");
    metrics.AddMeter("Microsoft.AspNetCore.Server.Kestrel");

    // Export the metrics via OTLP
    metrics.AddOtlpExporter(configureOtlp);
});

// Add Tracing for ASP.NET Core and our custom ActivitySource and export via OTLP
otel.WithTracing(tracing =>
{
    tracing.AddAspNetCoreInstrumentation();
    tracing.AddHttpClientInstrumentation();
    tracing.AddSource(greeterActivitySource.Name);
    tracing.AddOtlpExporter(configureOtlp);
});

Este código configura o OpenTelemetry com as diferentes fontes de telemetria:

  • Ele adiciona um provedor OTel a ILogger para coletar registros de log.
  • Ele configura métricas, registrando provedores de instrumentação e medidores para ASP.NET e o medidor personalizado.
  • Ele configura o rastreamento, registrando provedores de instrumentação e o elemento personalizado ActivitySource.

Em seguida, ele registra o exportador OTLP usando variáveis de ambiente para sua configuração.

6. Definir configurações OTLP

Você pode configurar o exportador OTLP por meio de APIs em código, variáveis de ambiente ou configuração de aplicativo. Para este exemplo, adicione as configurações OTLP na raiz de appsettings.Development.json, após a Logging seção:

{
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft.AspNetCore": "Warning"
    }
  },
  "OTEL_EXPORTER_OTLP_ENDPOINT": "http://localhost:4317",
  "OTEL_SERVICE_NAME": "OTLP-Example"
}

Adicione outras configurações para o exportador .NET OTLP ou configurações comuns do OTel, como OTEL_RESOURCE_ATTRIBUTES definir atributos de recurso.

Observação

ASP.NET Core carrega appsettings.json e appsettings.Development.json. As configurações em appsettings.Development.json substituem as configurações duplicadas em appsettings.json quando você executa o aplicativo no ambiente de Desenvolvimento.

7. Criar um endpoint de API

Insira o seguinte código entrebuilder.Build:app.Run()

app.MapGet("/", SendGreeting);

Inserir a seguinte função no final do arquivo:

async Task<string> SendGreeting(ILogger<Program> logger)
{
    // Create a new Activity scoped to the method
    using var activity = greeterActivitySource.StartActivity("GreeterActivity");

    // Log a message
    logger.LogInformation("Sending greeting");

    // Increment the custom counter
    countGreetings.Add(1);

    // Add a tag to the Activity
    activity?.SetTag("greeting", "Hello World!");

    return "Hello World!";
}

Observação

A definição de ponto de extremidade não usa nada específico para OpenTelemetry. Usa apenas as APIs do .NET para observabilidade.

8. Iniciar o contêiner Aspire Dashboard

Use docker para baixar e executar o contêiner do painel.

docker run --rm -it `
-p 18888:18888 `
-p 4317:18889 `
--name aspire-dashboard `
mcr.microsoft.com/dotnet/aspire-dashboard:latest

Os dados exibidos no painel podem ser confidenciais. Por padrão, o painel requer um token de autenticação para entrar. O contêiner exibe esse token em sua saída.

Aspire Painel

Copie a URL, substitua 0.0.0.0localhostpor , por exemplo, http://localhost:18888/login?t=123456780abcdef123456780e abra-a no navegador. Ou cole a chave após /login?t= na caixa de diálogo de login. O token é alterado sempre que você inicia o contêiner.

9. Executar o projeto

Execute o projeto com dotnet run. A saída do console exibe as URLs que o aplicativo escuta, por exemplo:

info: Microsoft.Hosting.Lifetime[14]
      Now listening on: http://localhost:5086

Use a porta mostrada em sua própria saída de console, pois pode ser diferente dos exemplos neste artigo. Use um navegador ou curl para acessar a API nessa porta:

curl -k http://localhost:5086

Cada vez que você solicita a página, a contagem de saudações aumenta.

9.1 Saída de log

O código registra instruções usando ILogger. Por padrão, .NET habilita o Provedor de Console, que direciona a saída para o console.

Você pode exportar logs do .NET de várias formas:

  • Sistemas de contêineres, como stdout, redirecionam a saída de stderr e para arquivos de log.
  • Use bibliotecas de log que se integrem ao ILogger, como Serilog e NLog.
  • Use provedores de log para OTel, como OTLP. A seção de logging do código na etapa 5 adiciona o provedor OTel.

O painel exibe os logs na forma de logs estruturados. Todas as propriedades definidas na mensagem de log se tornam campos no registro de log.

Logs no painel de controle autônomo

9.2 Visão de métricas

O Aspire painel mostra as métricas por recurso. Um recurso é o termo OTel para uma fonte de telemetria, como um processo. Quando você seleciona um recurso, o painel lista cada métrica que o recurso enviou para seu ponto de extremidade OTLP. A lista de métricas é dinâmica e é atualizada à medida que o painel recebe novas métricas.

Métricas no painel autônomo

A exibição de métricas depende do tipo de métrica que você usa:

  • O painel mostra os contadores diretamente.
  • Para histogramas que rastreiam um valor por solicitação, como um período de tempo ou bytes enviados por solicitação, o painel coleta valores em uma série de buckets e grafa os percentis P50, P90 e P99. Os resultados do histograma podem incluir exemplos, que são pontos de dados individuais, juntamente com a ID de rastreamento/intervalo dessa solicitação. O painel mostra-os como ponto no grafo. Selecione um para navegar até o respectivo rastreamento, para que você possa ver o que causou esse valor. Esse recurso ajuda você a diagnosticar exceções.
  • As métricas podem incluir dimensões, que são pares de chave/valor associados a valores individuais. O painel agrega valores por dimensão. Use os menus suspensos na visualização para filtrar os resultados por dimensões específicas, como apenas GET solicitações ou uma rota de URL específica no ASP.NET.

9.3 Visualização de rastreamento

A visualização de rastreamento lista os rastreamentos. Cada rastreamento é um conjunto de atividades que compartilham a mesma ID de rastreamento. Os intervalos acompanham o trabalho e cada intervalo representa uma unidade de trabalho. O processamento de uma solicitação ASP.NET cria um intervalo. Fazer uma requisição HttpClient é um intervalo (span). Ao acompanhar o pai de cada intervalo, você cria uma hierarquia de intervalos que você pode visualizar. Ao coletar intervalos de cada recurso (processo), você pode acompanhar o trabalho em uma série de serviços. As solicitações HTTP incluem um cabeçalho que transmite a ID de rastreamento e a ID do span pai ao próximo serviço. Cada recurso deve coletar telemetria e enviá-la para o mesmo coletor, que, em seguida, agrega e apresenta uma hierarquia dos intervalos.

Rastreamentos no painel autônomo

O painel mostra uma lista de rastreamentos com informações resumidas. Sempre que o painel detecta intervalos com uma nova ID de rastreamento, ele adiciona uma linha à tabela. Selecione Exibição para mostrar todos os intervalos no rastreamento.

Extensões no painel autônomo

Selecione um span para exibir os detalhes dele, incluindo quaisquer propriedades do span, como a tag greeting que você definiu na etapa 7.