Telemetria de latência do cliente HTTP no .NET

Quando você cria aplicativos que se comunicam por HTTP, é importante observar as características de desempenho da solicitação. A AddHttpClientLatencyTelemetry extensão permite a coleta de informações de tempo detalhadas para chamadas HTTP de saída sem alterações no código de chamada. Ele se conecta ao pipeline existente HttpClientFactory para capturar intervalos de estágio em todo o ciclo de vida da solicitação, registrar detalhes do protocolo HTTP, medir o impacto da coleta de lixo em que o runtime expõe esses dados e emitir uma forma de telemetria uniforme adequada para análise e ajuste de desempenho. Habilite essa telemetria chamando o AddHttpClientLatencyTelemetry() método de extensão. O manipulador embutido cria uma ILatencyContext para cada solicitação de saída e preenche as medidas até que o pipeline interno seja concluído. Consuma-os após await base.SendAsync(...) em um manipulador de delegação subsequente (adicionado após a telemetria) e exporte para o back-end de métricas. Exemplo:

Registrar método de extensão

using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Http.Diagnostics;
using Microsoft.Extensions.Hosting;

var builder = Host.CreateApplicationBuilder(args);

// An example of some accessor that is able to read latency context
builder.Services.AddSingleton<ILatencyContextAccessor, LatencyContextAccessor>();

// Register HTTP client latency telemetry first so its delegating handler runs earlier.
builder.Services.AddHttpClientLatencyTelemetry();

// Register export handler (runs after telemetry; sees finalized ILatencyContext).
builder.Services.AddTransient<HttpLatencyExportHandler>();

// Register an HttpClient that will emit and export latency measures.
builder.Services
    .AddHttpClient("observed")
    .AddHttpMessageHandler<HttpLatencyExportHandler>();

var host = builder.Build();
await host.RunAsync();

Acesse o contexto:

public sealed class HttpLatencyExportHandler : DelegatingHandler
{
    // ILatencyContextAccessor is just an example of some accessor that is able to read latency context
    private readonly ILatencyContextAccessor _latency;

    public HttpLatencyExportHandler(ILatencyContextAccessor latency) => _latency = latency;

    protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken ct)
    {
        var rsp = await base.SendAsync(request, ct).ConfigureAwait(false);

        var ctx = _latency.Current;
        if (ctx != null)
        {
            var data = ctx.LatencyData;
            // Record/export gc and conn with version as a dimension here.
        }
        return rsp;
    }
}

Adicionar o pacote

dotnet add package Microsoft.Extensions.Http.Diagnostics --version 9.10.0

Para obter mais informações, consulte dotnet package add ou Gerenciar dependências de pacotes em aplicativos .NET.

Registrar telemetria de latência do cliente HTTP

Para adicionar a telemetria de latência do cliente HTTP ao seu aplicativo, chame o AddHttpClientLatencyTelemetry método de extensão ao configurar seus serviços:

var builder = WebApplication.CreateBuilder(args);

// Add HTTP client factory
builder.Services.AddHttpClient();

// Add HTTP client latency telemetry
builder.Services.AddHttpClientLatencyTelemetry();

Esse registro adiciona um DelegatingHandler a todos os clientes HTTP criados por meio de IHttpClientFactory, coletando informações detalhadas de latência para cada solicitação.

Configurar opções de telemetria

Você configura a coleção de telemetria por meio do HttpClientLatencyTelemetryOptions (padrão de opções padrão). ** Você pode fornecer valores usando um delegado ou por meio de configuração de associação (por exemplo, appsettings.json). A instância de opções é resolvida uma vez por pipeline de tratadores, de modo que as alterações sejam aplicadas a novos clientes e tratadores.

// Configure with delegate
builder.Services.AddHttpClientLatencyTelemetry(options =>
{
    options.EnableDetailedLatencyBreakdown = true;
});

// Or configure from configuration
builder.Services.AddHttpClientLatencyTelemetry(
builder.Configuration.GetSection("HttpClientTelemetry"));

Opções de configuração

A HttpClientLatencyTelemetryOptions classe oferece as seguintes configurações:

Opção Tipo Padrão Description Quando desabilitar
HabilitarDetalhamentoDetlatência booleano true Permite o detalhamento preciso das fases de tempo para cada solicitação do HttpClient (por exemplo, estabelecimento da conexão, cabeçalhos enviados, primeiro byte recebido, conclusão) para produzir uma divisão da latência total. Adiciona um pequeno custo de medição de CPU/tempo extra, sem sobrecarga de fio. Defina como false apenas em cenários de taxa de transferência muito alta onde a sobrecarga mínima é necessária e apenas a duração total é suficiente.

Dados de telemetria coletados

Quando a telemetria de latência do cliente HTTP está habilitada, ela captura timestamps das fases, medidas específicas (onde há suporte) e atributos de protocolo utilizados na análise de desempenho.

Pontos de verificação de tempo

Os timestamps são registrados para os principais estágios do ciclo de vida da solicitação HTTP:

Phase Iniciar Evento Evento final Anotações
Resolução DNS Http.NameResolutionStart Http.NameResolutionEnd Pesquisa de nome do host (pode ser armazenada em cache ou ignorada).
Conexão de soquete Http.SocketConnectStart Http.SocketConnectEnd CP (e handshake do TLS, se combinado pelo manipulador).
Estabelecimento de conexão Http.ConnectionEstablished Marca a conexão utilizável após o handshake.
Cabeçalhos da solicitação Http.RequestHeadersStart Http.RequestHeadersEnd Gravando cabeçalhos de solicitação no fio/buffer.
Conteúdo da solicitação Http.RequestContentStart Http.RequestContentEnd Corpo da solicitação de streaming ou buffer.
Cabeçalhos de resposta Http.ResponseHeadersStart Http.ResponseHeadersEnd Primeiro byte para conclusão da análise de cabeçalho.
Conteúdo da resposta Http.ResponseContentStart Http.ResponseContentEnd Lendo o corpo completo da resposta (até a conclusão ou descarte).

Medidas (dependentes da plataforma)

As medidas quantificam os fatores de latência que os pontos de verificação de fase brutos não podem (sobreposição de pausa de GC, mudança de conexão, outras contagens ou durações acumuladas). Eles são coletados em um contexto de latência na memória criado quando você chama AddHttpClientLatencyTelemetry(). Nada é emitido automaticamente: o contexto simplesmente acumula pontos de verificação, medidas e marcas até que a solicitação seja concluída. Se você também habilitar o enriquecimento de log do cliente HTTP com AddExtendedHttpClientLogging(), o contexto concluído será mesclado em um único campo de log estruturado chamado LatencyInfo (marcador de versão, nome do servidor, se disponível, em seguida tag, ponto de verificação e sequências de nome/valor da medida).

Esse campo de log é o único artefato de saída interno; nenhuma métrica ou rastreamento é produzido, a menos que você adicione seu próprio exportador. Para exibi-las como métricas, leia o contexto após o pipeline de solicitação retornar e registre (por exemplo) a sobreposição de pausa do GC em um histograma e as iniciações de conexão em um contador, opcionalmente dimensionados por versão do protocolo.

Nome Description
Http.GCPauseTime Duração total da pausa do GC sobrepondo a solicitação.
Http.ConnectionInitiated (Conexão Iniciada) Emitido quando uma nova conexão subjacente (não reutilização em pool) é criada.

Etiquetas

Use marcas para anexar dimensões categóricas estáveis a cada solicitação para que você possa segmentar, filtrar e agregar métricas e logs sem reprocessar dados brutos. Eles são rótulos de classificação de baixa cardinalidade (não intervalos) capturados no contexto de latência e, se o enriquecimento de log do cliente HTTP estiver habilitado, serializados em um único campo de log LatencyInfo. Habilite o enriquecimento na inicialização do aplicativo adicionando a extensão de log (para todos os clientes ou por cliente) juntamente com a telemetria de latência, por exemplo:

var builder = Host.CreateApplicationBuilder(args);
builder.Services.AddHttpClientLatencyTelemetry(); // enables latency context + measures/tags
builder.Services.AddExtendedHttpClientLogging();
var app = builder.Build();

Depois disso, as solicitações de saída registradas por meio do pipeline de log estruturado incluirão a LatencyInfo propriedade contendo as etiquetas achatadas, checkpoints e medidas. Nenhuma métrica ou rastro é emitido automaticamente para etiquetas; exporte-os manualmente (por exemplo, transforme valores de etiqueta em dimensões de métrica ou Activity etiquetas) se precisar deles fora dos logs.

Etiqueta Description
Http.Version Versão do protocolo HTTP negociada/usada (por exemplo, 1.1, 2, 3).

Exemplo de utilização

Esses componentes permitem acompanhar e relatar a latência do processamento de solicitação de cliente HTTP.

Você pode registrar os serviços usando os seguintes métodos:

public static IServiceCollection AddHttpClientLatencyTelemetry(
    this IServiceCollection services);

public static IServiceCollection AddHttpClientLatencyTelemetry(
    this IServiceCollection services,
    IConfigurationSection section);

public static IServiceCollection AddHttpClientLatencyTelemetry(
    this IServiceCollection services,
    Action<HttpClientLatencyTelemetryOptions> configure);

Por exemplo:

var builder = Host.CreateApplicationBuilder(args);

// Register IHttpClientFactory:
builder.Services.AddHttpClient();

// Register redaction services:
builder.Services.AddRedaction();

// Register latency context services:
builder.Services.AddLatencyContext();

// Register HttpClient logging enrichment & redaction services:
builder.Services.AddExtendedHttpClientLogging();

// Register HttpClient latency telemetry services:
builder.Services.AddHttpClientLatencyTelemetry();

var host = builder.Build();

Considerações sobre a plataforma

A telemetria de latência do cliente HTTP é executada em todos os destinos com suporte (.NET 9, .NET 8, .NET Standard 2.0 e .NET Framework 4.6.2). Os pontos de verificação de tempo essenciais são sempre coletados. A métrica de pausa do GC (Http.GCPauseTime) é emitida somente ao ser executada no .NET 8 ou no .NET 9. A implementação detecta os recursos da plataforma em runtime e habilita o que tem suporte sem configuração adicional.