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.
Para obter mais informações sobre o .NET Aspire, consulte:
- Visão geral do Aspire
- Telemetria no Aspire
- Aspire Dashboard
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:
Adicione o ServiceDefaults projeto à solução usando Adicionar Novo Projeto no Visual Studio ou use
dotnet new
:dotnet new aspire-servicedefaults --output ServiceDefaults
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.
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:
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.
Crie um App Inicial Aspire 9 .NET usando
dotnet new
:dotnet new aspire-starter-9 --output ConnectionTracingDemo
Ou no Visual Studio:
Abra
Extensions.cs
no projetoServiceDefaults
e edite o métodoConfigureOpenTelemetry
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.*"); });
Navegue até à página de Meteorologia da aplicação
webfrontend
para gerar uma solicitação deHttpClient
paraapiservice
.Retorne ao Painel e navegue até a página Rastreamentos. Abra o rastro
webfrontend: GET /weather
.
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çãoHttpClient
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.
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 connect
e 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.