Partilhar via


Rastreio distribuído nas bibliotecas System.Net

de rastreamento distribuído é uma técnica de diagnóstico que ajuda os engenheiros a localizar falhas e problemas de desempenho em aplicativos, especialmente aqueles que são distribuídos em várias máquinas ou processos. Essa técnica rastreia solicitações por meio de um aplicativo, correlacionando o trabalho feito por diferentes componentes e separando-o de outro trabalho que o aplicativo pode estar fazendo para solicitações simultâneas. Por exemplo, uma solicitação para um serviço Web típico pode ser recebida primeiro por um balanceador de carga e, em seguida, encaminhada para um processo de servidor Web, que então faz várias consultas a um banco de dados. O rastreamento distribuído permite que os engenheiros distingam se alguma dessas etapas falhou e quanto tempo cada etapa levou. Pode também registar mensagens produzidas por cada etapa à medida que é executada.

O sistema de rastreamento em .NET foi projetado para funcionar com OpenTelemetry (OTel) e usa OTel para exportar os dados para sistemas de monitoramento. O rastreamento no .NET é implementado usando as APIs System.Diagnostics, onde a classe System.Diagnostics.Activity representa uma unidade de trabalho, que corresponde a um OTel. OpenTelemetry define um esquema de nomenclatura padrão ao nível da indústria para intervalos (atividades), juntamente com seus atributos (etiquetas), conhecido como convenções semânticas. A telemetria .NET usa convenções semânticas existentes sempre que possível.

Observação

Os termos abrangem e atividade são sinônimo neste artigo. No contexto do código .NET, eles se referem a uma instância System.Diagnostics.Activity. Não confunda o elemento span do OTel com o System.Span<T>.

Dica

Para obter uma lista abrangente de todas as atividades internas, juntamente com suas tags/atributos, consulte Atividades internas no .NET.

Instrumentação

Para emitir rastreamentos, as bibliotecas de System.Net são instrumentadas com fontes de ActivitySource internas, que criam objetos Activity para acompanhar o trabalho executado. As atividades são criadas apenas se existirem ouvintes inscritos no ActivitySource.

A instrumentação interna evoluiu com as versões .NET.

  • No .NET 8 e anteriores, a instrumentação é limitada à criação de uma atividade de solicitação de cliente HTTP vazia. Isso significa que os usuários precisam confiar na biblioteca de OpenTelemetry.Instrumentation.Http para preencher a atividade com as informações (por exemplo, tags) necessárias para emitir rastreamentos úteis.
  • O .NET 9 estendeu a instrumentação emitindo o nome, o status, as informações de exceção e as tags mais importantes de acordo com as convenções semânticas do cliente OTel HTTP na atividade de solicitação do cliente HTTP. Isso significa que no .NET 9+, a dependência de OpenTelemetry.Instrumentation.Http pode ser omitida, a menos que recursos mais avançados, como de enriquecimento, sejam necessários.
  • O .NET 9 também introduziu o rastreamento de conexão experimental , adicionando novas atividades nas bibliotecas System.Net para apoiar o diagnóstico de problemas de conexão.

Recolher registos do System.Net

No nível mais baixo, a coleta de rastreamento é suportada por meio do método AddActivityListener, que registra ActivityListener objetos que contêm lógica definida pelo usuário.

No entanto, como desenvolvedor de aplicativos, você provavelmente preferiria confiar no rico ecossistema criado com base nos recursos fornecidos pelo OpenTelemetry .NET SDK para coletar, exportar e monitorar rastreamentos.

  • Para obter uma compreensão fundamental sobre a coleta de rastreamento com o OTel, consulte nosso guia sobre coleta de rastreamentos usando o OpenTelemetry.
  • Para coleta e monitoramento de rastreamento de em tempo de produção, você pode usar o OpenTelemetry com Prometheus, Grafana e Jaeger ou com o Azure Monitor e o Application Insights. No entanto, essas ferramentas são bastante complexas e podem ser inconvenientes de usar no momento do desenvolvimento.
  • Para coleta e monitoramento de rastreamento de em tempo de desenvolvimento, recomendamos o uso do .NET Aspire que fornece uma maneira simples, mas extensível, de iniciar o rastreamento distribuído em seu aplicativo e diagnosticar problemas localmente.
  • Também é possível reutilizar os Padrões do Serviço Aspire projeto sem a orquestração do Aspir. Esta é uma maneira prática de introduzir e configurar o rastreamento e as métricas do OpenTelemetry em seus projetos ASP.NET.

Colete rastreamentos com o .NET Aspire

Uma maneira simples de coletar rastreamentos e métricas em aplicativos ASP.NET é usar .NET Aspire. O .NET Aspire é um conjunto de extensões para o .NET para facilitar a criação e o trabalho com aplicativos distribuídos. Um dos benefícios de usar o .NET Aspire é que a telemetria é incorporada, usando as bibliotecas OpenTelemetry para .NET.

Os modelos de projeto padrão para o .NET Aspire contêm um projeto ServiceDefaults. Cada serviço na solução .NET Aspire tem uma referência ao projeto Service Defaults. Os serviços usam-no para instalar e configurar o OTel.

O modelo de projeto Service Defaults inclui os pacotes OTel SDK, ASP.NET, HttpClient e Runtime Instrumentation. Esses componentes de instrumentação são configurados no arquivo Extensions.cs. Para suportar a visualização por telemetria no Aspire Dashboard, o projeto Service Defaults também inclui o exportador OTLP por predefinição.

O Aspire Dashboard foi concebido para trazer a observação de telemetria para o ciclo de depuração local, o que permite aos programadores garantir que as aplicações estão a produzir telemetria. A visualização por telemetria também ajuda a diagnosticar esses aplicativos localmente. Ser capaz de observar as chamadas entre serviços é tão útil no momento da depuração quanto na produção. O painel do .NET Aspire é iniciado automaticamente quando você F5 o projeto AppHost do Visual Studio ou dotnet run o projeto AppHost da linha de comando.

Aspire Dashboard

Para obter mais informações sobre o .NET Aspire, consulte:

Reutilizar o projeto Service Defaults sem o .NET Aspire Orchestration

O projeto Aspire Service Defaults fornece uma maneira fácil de configurar o OTel para projetos ASP.NET, mesmo que não use o resto do .NET Aspire como o AppHost para orquestração. O projeto Service Defaults está disponível como um modelo de projeto via Visual Studio ou dotnet new. Ele configura OTel e configura o exportador OTLP. Em seguida, pode usar as variáveis de ambiente OTel para configurar o ponto de extremidade OTLP para onde enviar a telemetria e fornecer as propriedades dos recursos para a aplicação.

As etapas para usar ServiceDefaults fora do .NET Aspire são:

  1. Adicione o ServiceDefaults projeto à solução usando Adicionar Novo Projeto no Visual Studio ou use dotnet new:

    dotnet new aspire-servicedefaults --output ServiceDefaults
    
  2. Faça referência ao projeto ServiceDefaults a partir do seu aplicativo ASP.NET. No Visual Studio, selecione Adicionar>Referência de Projeto e selecione o projeto ServiceDefaults.

  3. Chame a função de configuração OpenTelemetry ConfigureOpenTelemetry() como parte da inicialização do construtor de aplicativos.

    var builder = WebApplication.CreateBuilder(args)
    builder.ConfigureOpenTelemetry(); // Extension method from ServiceDefaults.
    var app = builder.Build();
    app.MapGet("/", () => "Hello World!");
    app.Run();
    

Para obter um passo a passo completo, consulte Exemplo: Usar OpenTelemetry com OTLP e o Painel de Instrumentos Aspire autónomo.

Rastreio experimental de ligações

Ao solucionar problemas HttpClient ou gargalos, pode ser crucial ver onde o tempo está sendo gasto ao enviar solicitações HTTP. Muitas vezes, o problema ocorre durante o estabelecimento da conexão HTTP, que normalmente se divide em pesquisa de DNS, conexão TCP e handshake TLS.

.NET 9 introduziu o rastreamento de conexão experimental adicionando um span HTTP connection setup com três subspans representando as fases DNS, TCP e TLS do estabelecimento de conexão. A parte HTTP do rastreamento de conexão é implementada dentro SocketsHttpHandler, o que significa que o modelo de atividade deve respeitar o comportamento subjacente do pool de conexões.

Observação

Em SocketsHttpHandler, conexões e solicitações têm ciclos de vida independentes. Uma de conexão agrupada pode durar muito tempo e atender a muitas solicitações. Ao fazer uma solicitação, se não houver nenhuma conexão imediatamente disponível no pool de conexões, a solicitação será adicionada a uma fila de solicitações para aguardar uma conexão disponível. Não há relação direta entre solicitações em espera e conexões. O processo de conexão pode ter começado quando outra conexão ficou disponível para uso, caso em que a conexão liberada é usada. Como resultado, o HTTP connection setup span não é modelado como um filho do HTTP client request span; em vez disso, os links span são usados.

O .NET 9 introduziu as seguintes extensões para permitir a coleta de informações detalhadas de conexão:

Nome ActivitySource Descrição
HTTP wait_for_connection Experimental.System.Net.Http.Connections Subintervalo de HTTP client request que representa o intervalo de tempo em que a solicitação está aguardando uma conexão disponível na fila de espera.
HTTP connection_setup Experimental.System.Net.Http.Connections Representa o estabelecimento da conexão HTTP. Uma extensão de raiz de traço separada com seu próprio TraceId. HTTP client request spans podem conter links para HTTP connection_setup.
DNS lookup Experimental.System.Net.NameResolution Pesquisa de DNS realizada pela classe Dns.
socket connect Experimental.System.Net.Sockets Estabelecimento de uma ligação Socket.
TLS handshake Experimental.System.Net.Security O aperto de mão do cliente ou servidor TLS é realizado por SslStream.

Observação

Os nomes correspondentes de ActivitySource começam com o prefixo Experimental, pois esses intervalos podem ser alterados em versões futuras à medida que aprendemos mais sobre como funcionam em ambiente de produção.

Essas extensões são demasiado detalhadas para uso 24x7 em cenários de produção com cargas de trabalho elevadas - são ruidosas e este nível de instrumentação normalmente não é necessário. No entanto, se você estiver tentando diagnosticar problemas de conexão ou obter uma compreensão mais profunda de como a latência de rede e conexão está afetando seus serviços, eles fornecem informações difíceis de coletar por outros meios.

Quando o Experimental.System.Net.Http.Connections ActivitySource está habilitado, o HTTP client request span contém um link para o HTTP connection_setup span correspondente à conexão que atende à solicitação. Como uma conexão HTTP pode ser de longa duração, isso pode resultar em muitos links para a extensão de conexão de cada uma das atividades de solicitação. Algumas ferramentas de monitoramento de APM percorrem agressivamente links entre extensões para construir suas visualizações e, portanto, incluir essa extensão pode causar problemas quando as ferramentas não foram projetadas para levar em conta um grande número de links.

O diagrama a seguir ilustra o comportamento dos intervalos e a sua relação:

A conexão se estende ao longo do tempo.

Passo a passo: Usando o rastreamento de conexão experimental no .NET 9

Este passo a passo usa um aplicativo Aspire Starter .NET 9 para demonstrar a rastreabilidade de conexão, mas deve ser fácil configurá-lo também com outras ferramentas de monitorização. A etapa principal é habilitar o ActivitySources.

  1. Crie um App Inicial Aspire 9 .NET usando dotnet new:

    dotnet new aspire-starter-9 --output ConnectionTracingDemo
    

    Ou no Visual Studio:

    Criar um aplicativo .NET Aspire 9 Starter no Visual Studio

  2. Abra Extensions.cs no projeto ServiceDefaults e edite o método ConfigureOpenTelemetry adicionando o ActivitySources para conexão no retorno de chamada de configuração de rastreamento:

    .WithTracing(tracing =>
    {
        tracing.AddAspNetCoreInstrumentation()
            // Instead of using .AddHttpClientInstrumentation()
            // .NET 9 allows to add the ActivitySources directly.
            .AddSource("System.Net.Http")
            // Add the experimental connection tracking ActivitySources using a wildcard.
            .AddSource("Experimental.System.Net.*");
    });
    
  3. Inicie a solução. Isso deve abrir o painel do .NET Aspire .

  4. Navegue até à página de Meteorologia da aplicação webfrontend para gerar uma solicitação de HttpClient para apiservice.

  5. Retorne ao Painel e navegue até a página Rastreamentos. Abra o rastro webfrontend: GET /weather.

    Extensões HttpClient no Aspire Dashboard

Quando as solicitações HTTP são feitas com a instrumentação de conexão habilitada, você verá as seguintes alterações nas extensões de solicitação do cliente:

  • Se uma conexão precisar ser estabelecida, ou se o aplicativo estiver aguardando uma conexão do pool de conexões, uma extensão de HTTP wait_for_connection adicional será mostrada, o que representa o atraso para aguardar que uma conexão seja feita. Isso ajuda a entender os atrasos entre a solicitação HttpClient feita no código e quando o processamento da solicitação realmente começa. Na imagem anterior:
    • O intervalo selecionado é a solicitação HttpClient.
    • O intervalo abaixo representa o tempo que a solicitação passa aguardando que uma conexão seja estabelecida.
    • O último intervalo em amarelo é do destino que processa a solicitação.
  • A extensão HttpClient terá um link para a extensão HTTP connection_setup, que representa a atividade para criar a conexão HTTP usada pela solicitação.

configuração da ligação estende-se no Aspire Dashboard

Tal como mencionado anteriormente, o intervalo HTTP connection_setup é um segmento separado com a sua própria TraceId, uma vez que a sua vida útil é independente de cada solicitação individual do cliente. Essa extensão geralmente tem extensões filho DNS lookup, (TCP) socket connecte TLS client handshake.

Enriquecimento

Em alguns casos, é necessário melhorar a funcionalidade de rastreamento existente de System.Net. Normalmente, isso significa injetar tags/atributos adicionais para as atividades internas. A isto chama-se enriquecimento.

API de enriquecimento na biblioteca de instrumentação OpenTelemetry

Para adicionar tags ou atributos à atividade de solicitação do cliente HTTP, a abordagem mais simples é usar as APIs de enriquecimento HttpClient da biblioteca de instrumentação OpenTelemetry HttpClient e HttpWebRequest. Para tal, é necessário depender do pacote OpenTelemetry.Instrumentation.Http.

Enriquecimento manual

É possível implementar o enriquecimento da atividade HTTP client request manualmente. Para isso, você precisa acessar Activity.Current no código que está sendo executado no escopo da atividade de solicitação, antes que a atividade seja concluída. Isso pode ser feito implementando um IObserver<DiagnosticListener> e inscrevendo-o no AllListeners para obter chamadas de retorno quando a atividade de rede ocorrer. Na verdade, é assim que a biblioteca de instrumentação OpenTelemetry para HttpClient e HttpWebRequest é implementada. Para obter um exemplo de código, consulte o código de assinatura em DiagnosticSourceSubscriber.cs e a implementação subjacente em HttpHandlerDiagnosticListener.cs onde as notificações são delegadas.

Precisa de mais rastreamento?

Se você tiver sugestões para outras informações úteis que possam ser expostas por meio do rastreamento, crie um problema dotnet/runtime.