Partilhar via


Exemplo: Utilizar OpenTelemetry com OTLP e o Aspire Dashboard autónomo

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

Além de ser uma parte padrão do .NET Aspire, o Painel do Aspire está disponível como um contêiner docker autônomo, que fornece uma telemetria de ponto de extremidade OTLP para a qual pode ser enviada e visualizará os logs, métricas e rastreamentos. Usar o painel dessa maneira não depende do .NET Aspire, ele visualizará a telemetria de qualquer aplicativo que envie telemetria via OTLP. Funciona igualmente bem para aplicações escritas em Java, GoLang, Python etc. desde que eles possam enviar sua telemetria para um ponto de extremidade OTLP.

A utilização do Aspire Dashboard tem menos passos de configuração e configuração do que a utilização de soluções Open Source como o Prometheus, o Grafana e o Jaeger, mas, ao contrário dessas ferramentas, o Aspire Dashboard destina-se a ser uma ferramenta de visualização do programador e não à monitorização da produção.

1. Crie o projeto

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

dotnet new web

2. Adicione métricas e definições de atividade

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 da API

Inserir o seguinte entre builder.Build(); e app.Run()

app.MapGet("/", SendGreeting);

Insira a seguinte função na parte inferior do ficheiro:

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!";
}

Nota

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

4. Faça referência aos pacotes 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>

Nota

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

5. Configure o OpenTelemetry com os provedores corretos

Insira 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 fornecedores de instrumentação e medidores para ASP.NET e nosso medidor personalizado.
  • Ele configura o rastreamento, registrando provedores de instrumentação e nosso ActivitySource personalizado.

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

6. Configurar variáveis de ambiente OTLP

O exportador OTLP pode ser configurado via APIs em código, mas é mais comum configurá-lo via variáveis de ambiente. Adicione o seguinte ao 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.

Nota

Um problema comum é misturar AppSettings.json e AppSettings.Development.json, se este último estiver presente, ele será usado quando você F5 do Visual Studio e quaisquer configurações no AppSettings.json serão ignoradas.

7. Inicie o contentor do Aspire Dashboard

Use o 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 login. O token é exibido na saída resultante ao executar o contêiner.

[Painel de instrumentos do Aspire]

Copie o url mostrado, e substitua 0.0.0.0 por localhost, por exemplo http://localhost:18888/login?t=123456780abcdef123456780 , e abra isso em seu navegador, ou você também pode colar a chave depois quando /login?t= a caixa de diálogo de login é mostrada. O token mudará cada vez que você iniciar o contêiner.

8. Execute o projeto

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

curl -k http://localhost:7275

Cada vez que você solicitar a página, ela aumentará a contagem para o número de saudações que foram feitas.

8.1 Saída de log

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

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

  • stdout e stderr a saída é redirecionada para arquivos de log por sistemas de contêiner, como o Kubernetes.
  • Usando bibliotecas de log que se integrarão ao ILogger, elas incluem Serilog ou NLog.
  • Usando provedores de registro para OTel, como OTLP. A seção de registro 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.

Efetua login 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 para seu ponto de extremidade OTLP pelo recurso. A lista de métricas é dinâmica e será atualizada à medida que novas métricas forem recebidas.

Métricas em painel autônomo

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

  • Os contadores serão mostrados diretamente.
  • Os histogramas que rastreiam um valor por solicitação, como um intervalo de tempo ou bytes enviados por solicitação, são coletados em uma série de buckets. O painel representará graficamente os percentis P50, P90 e P99. Os resultados do histograma podem incluir exemplares, que são pontos de dados individuais juntamente com o rastreamento/spanId para essa solicitação. Estes serão mostrados como pontos no gráfico. Selecionar um navegará até o respetivo rastreamento para que você possa ver o que aconteceu para causar esse valor. Isso é útil para diagnosticar valores atípicos.
  • As métricas podem incluir dimensões, que são pares chave/valor associados a valores individuais. Os valores são agregados por dimensão. Usando os menus suspensos na exibição, você pode filtrar os resultados para examinar dimensões específicas, como apenas GET solicitações ou aquelas para uma rota de URL específica no ASP.NET.

8.3 Visualizando o rastreamento

O modo de exibição de rastreamento mostrará uma lista de rastreamentos - cada rastreamento é um conjunto de atividades que compartilham o mesmo traceId. O trabalho é acompanhado com vãos que representam uma unidade de trabalho. O processamento de uma solicitação de ASP.NET criará uma extensão. Fazer uma solicitação HttpClient será uma extensão. Ao rastrear o pai da extensão, uma hierarquia de extensões pode ser visualizada. Ao coletar extensões de cada recurso (processo), rastreamos o trabalho que acontece em uma série de serviços. As solicitações http têm um cabeçalho que é 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, agregará e apresentará uma hierarquia dos vãos.

Rastreamentos em painel autônomo

O painel mostrará uma lista de rastreamentos com informações resumidas. Sempre que forem vistos vãos com um novo traceId, eles obterão uma linha na tabela. Clicar em exibir mostrará todas as extensões no rastreamento.

Espans no painel autônomo

A seleção de uma extensão mostrará seus detalhes, incluindo quaisquer propriedades na extensão, como a greeting tag que definimos na etapa 3.