Partilhar via


Observabilidade .NET com OpenTelemetry

Ao executar um aplicativo, você quer saber o desempenho do aplicativo e detetar possíveis problemas antes que eles se tornem maiores. Você pode fazer isso emitindo dados de telemetria, como logs ou métricas, do seu aplicativo e, em seguida, monitorando e analisando esses dados.

O que é observabilidade?

A observabilidade no contexto de um sistema distribuído é a capacidade de monitorar e analisar a telemetria sobre o estado de cada componente, ser capaz de observar mudanças no desempenho e diagnosticar por que essas mudanças ocorrem. Ao contrário da depuração, que é invasiva e pode afetar a operação do aplicativo, a observabilidade destina-se a ser transparente para a operação principal e ter um impacto de desempenho pequeno o suficiente para que possa ser usada continuamente.

A observabilidade é comumente feita usando uma combinação de:

  • Logs, que registram operações individuais, como uma solicitação de entrada, uma falha em um componente específico ou um pedido sendo feito.
  • Métricas, que medem contadores e medidores, como número de solicitações concluídas, solicitações ativas, widgets que foram vendidos; ou um histograma da latência da solicitação.
  • Rastreamento distribuído, que rastreia solicitações e atividades entre componentes em um sistema distribuído para que você possa ver onde o tempo é gasto e rastrear falhas específicas.

Juntos, logs, métricas e rastreamento distribuído são conhecidos como os três pilares da observabilidade.

Cada pilar pode incluir dados de telemetria de:

  • O tempo de execução do .NET, como o coletor de lixo ou o compilador JIT.
  • Bibliotecas, tais como de Kestrel (o servidor web ASP.NET) e HttpClient.
  • Telemetria específica do aplicativo emitida pelo seu código.

Abordagens de observabilidade no .NET

Há algumas maneiras diferentes de alcançar a observabilidade em aplicativos .NET:

  • Explicitamente no código, fazendo referência e usando uma biblioteca como OpenTelemetry. Se você tem acesso ao código-fonte e pode reconstruir o aplicativo, então este é o mecanismo mais poderoso e configurável.
  • Fora do processo usando o EventPipe. Ferramentas como dotnet-monitor podem ouvir logs e métricas e, em seguida, processá-los sem afetar nenhum código.
  • Usando um gancho de inicialização, montagens podem ser injetadas no processo que pode coletar instrumentação. Um exemplo dessa abordagem é a Instrumentação Automática OpenTelemetry .NET.

O que é OpenTelemetry?

OpenTelemetry (OTel) é um padrão aberto multiplataforma para coletar e emitir dados de telemetria. OpenTelemetry inclui:

  • APIs para bibliotecas usarem para registrar dados de telemetria enquanto o código está em execução.
  • APIs que os desenvolvedores de aplicativos usam para configurar qual parte dos dados gravados será enviada pela rede, para onde serão enviados e como podem ser filtrados, armazenados em buffer, enriquecidos e transformados.
  • As convenções semânticas fornecem orientação sobre nomenclatura e conteúdo de dados de telemetria. É importante que os aplicativos que produzem dados de telemetria e as ferramentas que recebem os dados concordem sobre o que diferentes tipos de dados significam e que tipos de dados são úteis para que as ferramentas possam fornecer análises eficazes.
  • Uma interface para exportadores. Os exportadores são plugins que permitem que os dados de telemetria sejam transmitidos em formatos específicos para diferentes back-ends de telemetria.
  • O protocolo de fio OTLP é uma opção de protocolo de rede neutro do fornecedor para transmitir dados de telemetria. Algumas ferramentas e fornecedores suportam este protocolo, além dos protocolos proprietários pré-existentes que podem ter.

O uso do OTel permite o uso de uma ampla variedade de sistemas APM, incluindo sistemas de código aberto como Prometheus e Grafana, Azure Monitor - o produto APM da Microsoft no Azure, ou dos muitos fornecedores de APM que fazem parceria com a OpenTelemetry.

Existem implementações OpenTelemetry para a maioria das linguagens e plataformas, incluindo .NET.

Implementação .NET de OpenTelemetry

A implementação do .NET OpenTelemetry é um pouco diferente de outras plataformas, pois o .NET fornece log, métricas e APIs de atividade na estrutura. Isso significa que o OTel não precisa fornecer APIs para os autores de bibliotecas usarem. A implementação do .NET OTel usa estas APIs de plataforma para instrumentação:

Arquitetura OTel do .NET

Onde o OTel entra em jogo é que ele coleta telemetria dessas APIs e outras fontes (por meio de bibliotecas de instrumentação) e, em seguida, exporta-as para um sistema de monitoramento de desempenho de aplicativos (APM) para armazenamento e análise. O benefício que o OTel traz como padrão do setor é um mecanismo comum para coleta, esquemas e semânticas comuns para dados de telemetria e uma API para como os APMs podem se integrar ao OTel. Usar OTel significa que os aplicativos não precisam usar APIs ou estruturas de dados específicas do APM; eles funcionam contra o padrão OTel. Os APMs podem implementar um componente de exportador específico do APM ou usar OTLP, que é um novo padrão de fio para exportar dados de telemetria para os sistemas APM.

Pacotes OpenTelemetry

OpenTelemetry no .NET é implementado como uma série de pacotes NuGet que formam algumas categorias:

  • API principal
  • Instrumentação - esses pacotes coletam instrumentação do tempo de execução e bibliotecas comuns.
  • Exportadores - estes fazem interface com sistemas APM como Prometheus, Jaeger e OTLP.

A tabela a seguir descreve os principais pacotes.

Nome do Pacote Description
OpenTelemetria Biblioteca principal que fornece a funcionalidade OTEL principal
OpenTelemetry.Instrumentation.AspNetCore Instrumentação para ASP.NET Core e Peneireiro-das-torres
OpenTelemetry.Instrumentation.GrpcNetClient Instrumentação para gRPC Client para rastrear chamadas gRPC de saída
OpenTelemetry.Instrumentation.Http Instrumentação para HttpClient e HttpWebRequest para rastrear chamadas HTTP de saída
OpenTelemetry.Instrumentation.SqlClient Instrumentação usada SqlClient para rastrear operações de banco de dados
OpenTelemetry.Exporter.Console Exportador para o console, comumente usado para diagnosticar qual telemetria está sendo exportada
OpenTelemetry.Exporter.OpenTelemetryProtocol Exportador que utiliza o protocolo OTLP
OpenTelemetry.Exportador.Prometheus.AspNetCore Exportador para Prometheus implementado usando um ponto de extremidade ASP.NET Core
OpenTelemetry.Exporter.Zipkin Exportador para Zipkin tracing

Exemplo: Use Prometheus, Grafana e Jaeger

Este exemplo usa Prometheus para coleta de métricas, Grafana para criar um painel e Jaeger para mostrar rastreamento distribuído.

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 (OtPrGrYa.Example).

// Custom metrics for the application
var greeterMeter = new Meter("OtPrGrYa.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("OtPrGrJa.Example");

3. Criar um ponto de extremidade da API

app.MapGet("/", SendGreeting);
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 da API 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.Console" Version="1.5.0" />
   <PackageReference Include="OpenTelemetry.Exporter.OpenTelemetryProtocol" Version="1.5.0" />
   <PackageReference Include="OpenTelemetry.Exporter.Prometheus.AspNetCore" Version="1.5.0-rc.1" />
   <PackageReference Include="OpenTelemetry.Extensions.Hosting" Version="1.5.0" />
   <PackageReference Include="OpenTelemetry.Instrumentation.AspNetCore" Version="1.5.0-beta.1" />
   <PackageReference Include="OpenTelemetry.Instrumentation.Http" Version="1.5.0-beta.1" />
</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

var tracingOtlpEndpoint = builder.Configuration["OTLP_ENDPOINT_URL"];
var otel = builder.Services.AddOpenTelemetry();

// Configure OpenTelemetry Resources with the application name
otel.ConfigureResource(resource => resource
    .AddService(serviceName: builder.Environment.ApplicationName));

// Add Metrics for ASP.NET Core and our custom metrics and export to Prometheus
otel.WithMetrics(metrics => metrics
    // Metrics provider from OpenTelemetry
    .AddAspNetCoreInstrumentation()
    .AddMeter(greeterMeter.Name)
    // Metrics provides by ASP.NET Core in .NET 8
    .AddMeter("Microsoft.AspNetCore.Hosting")
    .AddMeter("Microsoft.AspNetCore.Server.Kestrel")
    .AddPrometheusExporter());

// Add Tracing for ASP.NET Core and our custom ActivitySource and export to Jaeger
otel.WithTracing(tracing =>
{
    tracing.AddAspNetCoreInstrumentation();
    tracing.AddHttpClientInstrumentation();
    tracing.AddSource(greeterActivitySource.Name);
    if (tracingOtlpEndpoint != null)
    {
        tracing.AddOtlpExporter(otlpOptions =>
         {
             otlpOptions.Endpoint = new Uri(tracingOtlpEndpoint);
         });
    }
    else
    {
        tracing.AddConsoleExporter();
    }
});

Esse código usa a instrumentação ASP.NET Core para obter métricas e atividades do ASP.NET Core. Ele também registra os Metrics e ActivitySource provedores para métricas e rastreamento, respectivamente.

O código usa o exportador Prometheus para métricas, que usa ASP.NET Core para hospedar o ponto de extremidade, então você também precisa adicionar:

// Configure the Prometheus scraping endpoint
app.MapPrometheusScrapingEndpoint();

6. 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. Você pode acessar o ponto de extremidade de métricas usando a mesma url base, com o caminho /metrics.

6.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 log para OTel, como OTLP ou o exportador do Azure Monitor mostrado mais abaixo.

6.2 Acesse as métricas

Você pode acessar as métricas usando o /metrics endpoint.

curl -k https://localhost:7275/
Hello World!

curl -k https://localhost:7275/metrics
# TYPE greetings_count counter
# HELP greetings_count Counts the number of greetings
greetings_count 1 1686894204856

# TYPE current_connections gauge
# HELP current_connections Number of connections that are currently active on the server.
current_connections{endpoint="127.0.0.1:7275"} 1 1686894204856
current_connections{endpoint="[::1]:7275"} 0 1686894204856
current_connections{endpoint="[::1]:5212"} 1 1686894204856
...

A saída de métricas é um instantâneo das métricas no momento em que o ponto de extremidade é solicitado. Os resultados são fornecidos em formato de exposição Prometheus, que é legível por humanos, mas melhor compreendido por Prometheus. Esse tema é abordado na próxima etapa.

6.3 Aceder ao rastreio

Se você olhar para o console para o servidor, verá a saída do exportador de rastreamento de console, que produz as informações em um formato legível por humanos. Isso deve mostrar duas atividades, uma do seu costume ActivitySourcee outra do ASP.NET Core:

Activity.TraceId:            2e00dd5e258d33fe691b965607b91d18
Activity.SpanId:             3b7a891f55b97f1a
Activity.TraceFlags:         Recorded
Activity.ParentSpanId:       645071fd0011faac
Activity.ActivitySourceName: OtPrGrYa.Example
Activity.DisplayName:        GreeterActivity
Activity.Kind:               Internal
Activity.StartTime:          2023-06-16T04:50:26.7675469Z
Activity.Duration:           00:00:00.0023974
Activity.Tags:
    greeting: Hello World!
Resource associated with Activity:
    service.name: OTel-Prometheus-Grafana-Jaeger
    service.instance.id: e1afb619-bc32-48d8-b71f-ee196dc2a76a
    telemetry.sdk.name: opentelemetry
    telemetry.sdk.language: dotnet
    telemetry.sdk.version: 1.5.0

Activity.TraceId:            2e00dd5e258d33fe691b965607b91d18
Activity.SpanId:             645071fd0011faac
Activity.TraceFlags:         Recorded
Activity.ActivitySourceName: Microsoft.AspNetCore
Activity.DisplayName:        /
Activity.Kind:               Server
Activity.StartTime:          2023-06-16T04:50:26.7672615Z
Activity.Duration:           00:00:00.0121259
Activity.Tags:
    net.host.name: localhost
    net.host.port: 7275
    http.method: GET
    http.scheme: https
    http.target: /
    http.url: https://localhost:7275/
    http.flavor: 1.1
    http.user_agent: curl/8.0.1
    http.status_code: 200
Resource associated with Activity:
    service.name: OTel-Prometheus-Grafana-Jaeger
    service.instance.id: e1afb619-bc32-48d8-b71f-ee196dc2a76a
    telemetry.sdk.name: opentelemetry
    telemetry.sdk.language: dotnet
    telemetry.sdk.version: 1.5.0

A primeira é a atividade personalizada interna que você criou. O segundo é criado por ASP.NET para a solicitação e inclui tags para as propriedades da solicitação HTTP. Você verá que ambos têm o mesmo TraceId, que identifica uma única transação e em um sistema distribuído pode ser usado para correlacionar os rastreamentos de cada serviço envolvido em uma transação. Os IDs são transmitidos como cabeçalhos HTTP. ASP.NET Core atribui um TraceId se nenhum estiver presente quando recebe uma solicitação. HttpClient Inclui os cabeçalhos por padrão em solicitações de saída. Cada atividade tem um SpanId, que é a combinação de TraceId e SpanId que identificam de forma única cada atividade. A Greeter atividade é parentada à atividade HTTP por meio de seu ParentSpanId, que mapeia para a SpanId atividade HTTP.

Em um estágio posterior, você alimentará esses dados no Jaeger para visualizar os rastreamentos distribuídos.

7. Colete métricas com Prometheus

Prometheus é um sistema de banco de dados de coleta de métricas, agregação e séries temporais. Você o configura com os pontos de extremidade métricos para cada serviço e ele periodicamente raspa os valores e os armazena em seu banco de dados de séries temporais. Em seguida, você pode analisá-los e processá-los conforme necessário.

Os dados de métricas expostos no formato Prometheus são um instantâneo point-in-time das métricas do processo. Cada vez que uma solicitação é feita para o ponto de extremidade de métricas, ele relatará os valores atuais. Embora os valores atuais sejam interessantes, eles se tornam mais valiosos quando comparados aos valores históricos para ver tendências e detetar se os valores são anômalos. Comumente, os serviços têm picos de uso com base na hora do dia ou eventos mundiais, como uma onda de compras na Black Friday. Ao comparar os valores com as tendências históricas, você pode detetar se elas são anormais ou se uma métrica está piorando lentamente ao longo do tempo.

O processo não armazena nenhum histórico desses instantâneos métricos. Adicionar essa capacidade ao processo pode exigir muitos recursos. Além disso, em um sistema distribuído, você geralmente tem várias instâncias de cada nó, portanto, deseja ser capaz de coletar as métricas de todas elas e, em seguida, agregar e comparar com seus valores históricos.

7.1 Instalar e configurar o Prometheus

Faça o download do https://prometheus.io/download/ Prometheus para a sua plataforma e extraia o conteúdo do download.

Observe a parte superior da saída do seu servidor em execução para obter o número da porta para o ponto de extremidade http . Por exemplo:

info: Microsoft.Hosting.Lifetime[14]
      Now listening on: https://localhost:7275
info: Microsoft.Hosting.Lifetime[14]
      Now listening on: http://localhost:5212

Modifique o arquivo de configuração do Prometheus YAML para especificar a porta para seu ponto de extremidade de raspagem HTTP e defina um intervalo de raspagem menor. Por exemplo:

  scrape_configs:
  # The job name is added as a label `job=<job_name>` to any timeseries scraped from this config.
  - job_name: "prometheus"
    - scrape_interval: 1s # poll very quickly for a more responsive demo

    # metrics_path defaults to '/metrics'
    # scheme defaults to 'http'.

    scrape_interval: 1s # poll very quickly for a more responsive demo
    static_configs:
      - targets: ["localhost:5212"]

Inicie o Prometheus e procure na saída a porta em que ele está sendo executado, normalmente 9090:

>prometheus.exe
...
ts=2023-06-16T05:29:02.789Z caller=web.go:562 level=info component=web msg="Start listening for connections" address=0.0.0.0:9090

Abra este URL no seu navegador. Na interface do usuário do Prometheus, agora você deve ser capaz de consultar suas métricas. Use o botão realçado na imagem a seguir para abrir o explorador de métricas, que mostra todas as métricas disponíveis.

Explorador de métricas Prometheus

Selecione a greetings_count métrica para ver um gráfico de valores.

Gráfico de greetings_count

8. Use o Grafana para criar um painel de métricas

Grafana é um produto de dashboarding que pode criar dashboards e alertas com base no Prometheus ou noutras fontes de dados.

Baixe e instale a versão OSS do Grafana https://grafana.com/oss/grafana/ seguindo as instruções para sua plataforma. Uma vez instalado, o Grafana é normalmente executado na porta 3000, por isso abra http://localhost:3000 no seu navegador. Terá de iniciar sessão; O nome de usuário e a senha padrão são ambos admin.

No menu hambúrguer, escolha conexões e insira o texto prometheus para selecionar o tipo de ponto final. Selecione Criar uma fonte de dados Prometheus para adicionar uma nova fonte de dados.

Ligação de grafana a Prometheus

Você precisa definir as seguintes propriedades:

  • URL do servidor Prometheus: http://localhost:9090/ alterando a porta conforme aplicável

Selecione Save & Test para verificar a configuração.

Depois de receber uma mensagem de sucesso, você pode configurar um painel. Clique no link de criação de um painel mostrado no pop-up para a mensagem de sucesso.

Selecione Adicionar uma visualização e, em seguida, escolha a fonte de dados Prometheus que você acabou de adicionar como a fonte de dados.

O designer do painel do painel deve aparecer. Na metade inferior da tela, você pode definir a consulta.

Consulta Grafana usando greetings_count

Selecione a greetings_count métrica e, em seguida, selecione Executar consultas para ver os resultados.

Com o Grafana, você pode projetar painéis sofisticados que rastrearão qualquer número de métricas.

Cada métrica no .NET pode ter dimensões adicionais, que são pares chave-valor que podem ser usados para particionar os dados. Todas as métricas ASP.NET apresentam uma série de dimensões aplicáveis ao contador. Por exemplo, o current-requests contador de Microsoft.AspNetCore.Hosting tem as seguintes dimensões:

Atributo Tipo Description Exemplos Presença
method string Método de solicitação HTTP. GET; POST; HEAD Sempre
scheme string O esquema de URI que identifica o protocolo usado. http; https Sempre
host string Nome do servidor HTTP local que recebeu a solicitação. localhost Sempre
port int Porta do servidor HTTP local que recebeu a solicitação. 8080 Adicionado se não for padrão (80 para http ou 443 para https)

Os gráficos em Grafana são geralmente particionados com base em cada combinação única de dimensões. As dimensões podem ser usadas nas consultas Grafana para filtrar ou agregar os dados. Por exemplo, se você criar um gráfico current_requests, verá valores particionados com base em cada combinação de dimensões. Para filtrar com base apenas no host, adicione uma operação de e use host como o valor do Sum rótulo.

Grafana current_requests por anfitrião

9. Rastreamento distribuído com Jaeger

Na etapa 6, você viu que as informações de rastreamento distribuído estavam sendo expostas ao console. Esta informação rastreia unidades de trabalho com atividades. Algumas atividades são criadas automaticamente pela plataforma, como a de ASP.NET para representar o tratamento de uma solicitação, e bibliotecas e código do aplicativo também podem criar atividades. O exemplo das saudações tem uma Greeter atividade. As atividades são correlacionadas usando as TraceIdtags , SpanId, e ParentId .

Cada processo em um sistema distribuído produz seu próprio fluxo de informações de atividade e, como métricas, você precisa de um sistema para coletar, armazenar e correlacionar as atividades para poder visualizar o trabalho feito para cada transação. Jaeger é um projeto de código aberto para permitir essa coleção e visualização.

Faça o download do arquivo de distribuição binária mais recente do Jaeger para sua plataforma em https://www.jaegertracing.io/download/.

Em seguida, extraia o download para um local de fácil acesso. Execute o executável jaeger-all-in-one(.exe ):

./jaeger-all-in-one --collector.otlp.enabled

Examine a saída do console para encontrar a porta onde ele está ouvindo o tráfego OTLP via gRPC. Por exemplo:

{"level":"info","ts":1686963686.3854616,"caller":"otlpreceiver@v0.78.2/otlp.go:83","msg":"Starting GRPC server","endpoint":"0.0.0.0:4317"}

Essa saída informa que está ouvindo no 0.0.0.0:4317, para que você possa configurar essa porta como o destino para seu exportador OTLP.

Abra o AppSettings.json arquivo para o nosso projeto e adicione a seguinte linha, alterando a porta, se aplicável.

"OTLP_ENDPOINT_URL" :  "http://localhost:4317/"

Reinicie o processo de rececionista para que ele possa pegar a alteração de propriedade e começar a direcionar as informações de rastreamento para Jaeger.

Agora, você deve ser capaz de ver a interface do usuário do Jaeger em http://localhost:16686/ a partir de um navegador da web.

Consulta Jaeger para rastreamentos

Para ver uma lista de rastreamentos, selecione OTel-Prometheus-grafana-Jaeger na lista suspensa Serviço . A seleção de um rastreamento deve mostrar um gráfico de gant das atividades como parte desse rastreamento. Clicar em cada uma das operações mostra mais detalhes sobre a atividade.

Detalhes da operação Jaeger

Em um sistema distribuído, você deseja enviar rastreamentos de todos os processos para a mesma instalação do Jaeger para que ele possa correlacionar as transações em todo o sistema.

Você pode tornar seu aplicativo um pouco mais interessante fazendo com que ele faça chamadas HTTP para si mesmo.

  • Adicionar uma HttpClient fábrica ao aplicativo

    builder.Services.AddHttpClient();
    
  • Adicionar um novo ponto de extremidade para fazer chamadas de saudação aninhadas

    app.MapGet("/NestedGreeting", SendNestedGreeting);
    
  • Implemente o ponto de extremidade para que ele faça chamadas HTTP que também possam ser rastreadas. Neste caso, ele chama de volta para si mesmo em um loop artificial (realmente aplicável apenas a cenários de demonstração).

    async Task SendNestedGreeting(int nestlevel, ILogger<Program> logger, HttpContext context, IHttpClientFactory clientFactory)
    {
        // Create a new Activity scoped to the method
        using var activity = greeterActivitySource.StartActivity("GreeterActivity");
    
        if (nestlevel <= 5)
        {
            // Log a message
            logger.LogInformation("Sending greeting, level {nestlevel}", nestlevel);
    
            // Increment the custom counter
            countGreetings.Add(1);
    
            // Add a tag to the Activity
            activity?.SetTag("nest-level", nestlevel);
    
            await context.Response.WriteAsync($"Nested Greeting, level: {nestlevel}\r\n");
    
            if (nestlevel > 0)
            {
                var request = context.Request;
                var url = new Uri($"{request.Scheme}://{request.Host}{request.Path}?nestlevel={nestlevel - 1}");
    
                // Makes an http call passing the activity information as http headers
                var nestedResult = await clientFactory.CreateClient().GetStringAsync(url);
                await context.Response.WriteAsync(nestedResult);
            }
        }
        else
        {
            // Log a message
            logger.LogError("Greeting nest level {nestlevel} too high", nestlevel);
            await context.Response.WriteAsync("Nest level too high, max is 5");
        }
    }
    

Isso resulta em um gráfico mais interessante com uma forma de pirâmide para as solicitações, já que cada nível aguarda a resposta da chamada anterior.

Resultados de dependência aninhados de Jaeger

Exemplo: Usar o Azure Monitor e o Application Insights

No exemplo anterior, você usou aplicativos de código aberto separados para métricas e rastreamento. Existem muitos sistemas APM comerciais disponíveis para escolher. No Azure, o principal produto de monitoramento de aplicativos é o Application Insights, que faz parte do Azure Monitor.

Uma das vantagens de um produto APM integrado é que ele pode correlacionar as diferentes fontes de dados de observabilidade. Para facilitar a experiência de ASP.NET com o Azure Monitor, é fornecido um pacote wrapper que faz a maior parte do trabalho pesado de configurar o OpenTelemetry.

Pegue o mesmo projeto da Etapa 5 e substitua as referências do NuGet por um único pacote:

<ItemGroup>
  <PackageReference Include="Azure.Monitor.OpenTelemetry.AspNetCore" Version="1.0.0-beta.4" />
</ItemGroup>

Em seguida, substitua o código de inicialização OTel por:

var otel = builder.Services.AddOpenTelemetry();
otel.UseAzureMonitor();
otel.WithMetrics(metrics => metrics
    .AddMeter(greeterMeter.Name)
    .AddMeter("Microsoft.AspNetCore.Hosting")
    .AddMeter("Microsoft.AspNetCore.Server.Kestrel"));
otel.WithTracing(tracing =>
{
    tracing.AddSource(greeterActivitySource.Name);
});

UseAzureMonitor() é a magia que adicionará as bibliotecas de instrumentação comuns e os exportadores do Application Insights. Você só precisa adicionar seu costume Meter e ActivitySource nomes ao registro.

Se ainda não for um cliente do Azure, pode criar uma conta gratuita em https://azure.microsoft.com/free/. Faça logon no Portal do Azure e selecione um recurso existente do Application Insights ou crie um novo com https://ms.portal.azure.com/#create/Microsoft.AppInsightso .

O Application Insights identifica qual instância usar para armazenar e processar dados por meio de uma chave de instrumentação e cadeia de conexão encontradas no canto superior direito da interface do usuário do portal.

Cadeia de conexão no Portal do Azure

Se você estiver usando o Serviço de Aplicativo do Azure, essa cadeia de conexão será passada automaticamente para o aplicativo como uma variável de ambiente. Para outros serviços ou ao executar localmente, você precisa passá-lo usando a APPLICATIONINSIGHTS_CONNECTION_STRING variável de ambiente ou em appsettings.json. Para executar localmente, é mais fácil adicionar o valor a appsettings.json:

"AzureMonitor": {
    "ConnectionString": "InstrumentationKey=12345678-abcd-abcd-abcd-12345678..."
}

Nota

Substitua o valor pelo da sua instância.

Quando você executa o aplicativo, a telemetria será enviada para o Application Insights. Agora você deve obter logs, métricas e rastreamentos distribuídos para seu aplicativo.

Registos

Visualização de logs do App Insights

Métricas

Visualização de métricas do App Insights

Rastreamento distribuído

Visualização de transação do App Insights