Compartilhar via


Exemplo: Use o OpenTelemetry com OTLP e o painel autônomo do Aspire

Este artigo é um de uma série de exemplos para ilustrar a observabilidade do .NET com o OpenTelemetry.

Além de ser uma parte padrão do Aspire, o Aspire Dashboard está disponível como um contêiner autônomo do Docker, que fornece um ponto de extremidade OTLP para o qual a telemetria pode ser enviada. O painel visualiza os logs, as métricas e os rastreamentos. O uso do painel dessa forma não tem dependência do Aspire, e visualiza a telemetria de qualquer aplicativo que envie telemetria por meio de OTLP. Ele funciona igualmente bem para aplicativos escritos em Java, GoLang ou Python, desde que possam enviar sua telemetria para um ponto de extremidade OTLP.

Usar o Painel do Aspire tem menos etapas de configuração e configuração do que usar soluções de Software Livre , como Prometheus, Grafana e Jaeger. Mas, ao contrário dessas ferramentas, o Painel aspire destina-se como uma ferramenta de visualização do desenvolvedor e não para 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. Adicionar definições de métricas e atividades

O código a seguir define uma nova métrica (greetings.count) para o número de vezes que a API foi chamada e uma nova fonte de atividade (Otel.Example).

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

3. Criar um ponto de extremidade de API

Inserir o código a seguir entre builder.Build(); e 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.

4. Referenciar os pacotes do OpenTelemetry

Use o Gerenciador de Pacotes NuGet ou a linha de comando para adicionar os seguintes pacotes NuGet:

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

Observação

Use as versões mais recentes, pois as APIs do OTel estão em constante evolução.

5. Configurar o OpenTelemetry com os provedores corretos

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

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

var otel = builder.Services.AddOpenTelemetry();

// 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 provides by ASP.NET Core in .NET 8
    metrics.AddMeter("Microsoft.AspNetCore.Hosting");
    metrics.AddMeter("Microsoft.AspNetCore.Server.Kestrel");
});

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

// Export OpenTelemetry data via OTLP, using env vars for the configuration
var OtlpEndpoint = builder.Configuration["OTEL_EXPORTER_OTLP_ENDPOINT"];
if (OtlpEndpoint != null)
{
    otel.UseOtlpExporter();
}

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

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

Em seguida, ele registra o exportador OTLP usando env vars para sua configuração.

6. Configurar variáveis ​​de ambiente OTLP

O exportador OTLP pode ser configurado por meio de APIs no código, mas é mais comum configurá-lo por meio de variáveis de ambiente. Adicione o seguinte a AppSettings.Development.json

"OTEL_EXPORTER_OTLP_ENDPOINT": "http://localhost:4317",
"OTEL_SERVICE_NAME": "OTLP-Example"

Você pode adicionar variáveis de ambiente adicionais para o Exportador de OTLP do .NET ou variáveis OTel comuns, como OTEL_RESOURCE_ATTRIBUTES para definir atributos de recurso.

Observação

Um gotcha comum é misturar AppSettings.json e AppSettings.Development.json. Se este último estiver presente, ele será usado quando você pressionar F5 no Visual Studio, e todas as configurações no AppSettings.json serão ignoradas.

7. Inicie o contêiner do 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 é protegido com autenticação que requer um token para fazer logon. O token é exibido na saída resultante ao executar o contêiner.

Painel do Aspire Painel do Aspire

Copie a URL mostrada e substitua 0.0.0.0localhostpor, por exemplo, http://localhost:18888/login?t=123456780abcdef123456780e abra-a no navegador. Ou você também pode colar a chave depois de /login?t= quando a caixa de diálogo de login for exibida. O token é alterado sempre que você inicia o contêiner.

8. Executar o projeto

Execute o projeto e acesse a API com o navegador ou curl.

curl -k http://localhost:7275

Cada vez que você solicita a página, ela incrementa a contagem do número de saudações que foram feitas.

8.1 Saída dos logs

As instruções de registro em log do código são geradas usando ILogger. Por padrão, o Provedor de Console está habilitado para que a saída seja direcionada para o console.

Há algumas opções de como os logs podem ser retirados do .NET:

  • As saídas stdout e stderr são redirecionadas para arquivos de log por sistemas de contêiner, como o Kubernetes.
  • Usando bibliotecas de log que se integram ao ILogger. Essas bibliotecas incluem Serilog e NLog.
  • Usando provedores de log para OTel, como OTLP. A seção de log no código da etapa 5 adiciona o provedor OTel.

Os logs são mostrados no painel como logs estruturados - todas as propriedades definidas na mensagem de log são extraídas como campos no registro de log.

Logs no painel autônomo

8.2 Visualizando as métricas

O painel do Aspire mostra métricas por recurso (um recurso é a maneira OTel de falar sobre fontes de telemetria, como um processo). Quando um recurso é selecionado, o painel enumera cada métrica que foi enviada pelo recurso ao endpoint OTLP. A lista de métricas é dinâmica e é atualizada à medida que novas métricas são recebidas.

Métricas no painel autônomo

A exibição das métricas depende do tipo de métrica que está sendo usada:

  • Os contadores são mostrados diretamente.
  • Os histogramas que rastreiam um valor por solicitação, como um período de tempo ou bytes enviados por solicitação, são coletados em uma série de buckets. O painel grafa os percentis P50, P90 e P99. Os resultados do histograma podem incluir exemplares, que são pontos de dados individuais junto com o trace/spanId para essa solicitação. Eles são mostrados como ponto no grafo. Selecionar uma opção navega até a trilha respectiva para que você possa ver o que aconteceu que levou a esse valor. Isso é útil para diagnosticar valores discrepantes.
  • As métricas podem incluir dimensões, que são pares de chave/valor associados a valores individuais. Os valores são agregados por dimensão. Usando os menus suspensos na visualização, você pode filtrar os resultados para examinar dimensões específicas, como apenas solicitações GET, ou aquelas para uma rota específica de URL em ASP.NET.

8.3 Visualizando o rastreamento

A visão de rastreamento mostra uma lista de rastreamentos. Cada traço é um conjunto de atividades que compartilham o mesmo ID de traço. O trabalho é monitorado com segmentos, que representam uma unidade de operação. O processamento de uma solicitação ASP.NET cria um intervalo. Fazer uma solicitação HttpClient é um intervalo. Ao rastrear o pai do intervalo, uma hierarquia de intervalos pode ser visualizada. Ao coletar intervalos de cada recurso (processo), você pode acompanhar o trabalho que acontece em uma série de serviços. As requisições HTTP têm um cabeçalho usado para passar o traceId e o spanId pai para o próximo serviço. Cada recurso precisa coletar telemetria e enviá-la para o mesmo coletor. Em seguida, ele agregará e apresentará uma hierarquia dos intervalos.

Rastreamentos no painel autônomo

O painel mostra uma lista de rastreamentos com informações resumidas. Sempre que segmentos com um novo traceId são identificados, eles recebem uma linha na tabela. Clicar no modo de exibição mostra todos os intervalos no rastreamento.

Extensões no painel autônomo

Selecionar um intervalo mostra seus detalhes, incluindo quaisquer propriedades no intervalo, como a greeting marca que você definiu na etapa 3.