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 detalhadas de tempo para chamadas HTTP de saída sem alterações no código de chamada. Liga-se ao pipeline existente HttpClientFactory para captar os tempos das fases ao longo do ciclo de vida dos pedidos, registar detalhes do protocolo HTTP, medir o impacto da recolha de lixo onde o tempo de execução expõe esses dados e emitir uma forma de telemetria uniforme adequada para análise e ajuste de desempenho. Ative esta telemetria chamando o método de extensão AddHttpClientLatencyTelemetry(). O manipulador incorporado cria uma ILatencyContext solicitação para cada saída e preenche as medidas quando o pipeline interno é concluído. Consuma-os depois await base.SendAsync(...) num manipulador de delegação posterior (adicionado após a telemetria) e exporte para o seu sistema de métricas. Exemplo:

Método de extensão de registro

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();

Aceda ao 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 Manage package dependencies in .NET applications.

Registar a telemetria de latência do cliente HTTP

Para adicionar telemetria de latência de cliente HTTP à sua aplicação, chame o método AddHttpClientLatencyTelemetry 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 através do IHttpClientFactory, coletando informações detalhadas de latência para cada solicitação.

Configurar opções de telemetria

Você configura a coleta de telemetria por meio do HttpClientLatencyTelemetryOptions (padrão de opções padrão). Você pode fornecer valores com um delegado ou vinculando a configuração (por exemplo, appsettings.json). A instância de opções é resolvida uma vez por pipeline do manipulador, para que as alterações se apliquem a novos clientes e manipuladores.

// 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 Default Description Quando desativar
AtivarDesagregaçãoDetalhadaDeLatência booleano true Permite a temporização detalhada de cada solicitação HttpClient (por exemplo, estabelecimento de conexão, envio dos cabeçalhos, primeiro byte, conclusão) para criar uma decomposição da latência total. Adiciona um pequeno custo extra de medição de CPU/tempo, sem sobrecarga de fio. Defina apenas false em cenários de taxa de transferência muito alta, onde uma sobrecarga mínima é necessária e a duração total por si só é suficiente.

Dados de telemetria recolhidos

Quando a telemetria de latência do cliente HTTP está ativada, captura os carimbos de data/hora das fases, as medidas selecionadas (quando suportadas) e os atributos do protocolo utilizados na análise de desempenho.

Pontos de verificação de cronometragem

Os marcadores de tempo são registados para os principais estágios do ciclo de vida de uma solicitação HTTP.

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

Medidas (dependente da plataforma)

As medidas quantificam os fatores de latência que pontos de verificação de fase bruta não conseguem quantificar (sobreposição de pausas do GC, alterações de conexão, outras contagens acumuladas ou durações). 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 tags 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á nivelado em um único campo de log estruturado chamado LatencyInfo (marcador de versão, nome do servidor, se disponível, tag, ponto de verificação e sequências de nome/valor de 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 apresentá-los como métricas, leia o contexto após a resposta do pipeline de solicitação e registre (por exemplo) a sobreposição da pausa do GC em um histograma e as iniciações de conexão em um contador, opcionalmente categorizadas por versão do protocolo.

Nome Description
Http.GCPauseTime Duração total da pausa do GC que se sobrepõe à solicitação.
Http.ConnectionInitiated Emitido quando uma nova conexão subjacente (não reutilização em pool) é criada.

Etiquetas

Use tags 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 temporizações) capturados no contexto da latência e, se o enriquecimento do log do cliente HTTP estiver habilitado, serializados num único campo de log de LatencyInfo. Ative o enriquecimento na inicialização da aplicação ao adicionar a extensão de registo (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 que contém as tags achatadas, pontos de verificação e medidas. Nenhuma métrica ou rastreamento é emitido automaticamente para tags; exporte-os você mesmo (por exemplo, transforme valores de tags em dimensões métricas ou Activity tags) se precisar deles fora dos logs.

Tag Description
Versão HTTP Versão do protocolo HTTP negociada/utilizada (por exemplo, 1.1, 2, 3).

Exemplo de utilização

Esses componentes permitem rastrear e relatar a latência do processamento de solicitações de clientes 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 suportados (.NET 9, .NET 8, .NET Standard 2.0 e .NET Framework 4.6.2). Os pontos de verificação de tempo centrais são sempre coletados. A métrica de pausa GC (Http.GCPauseTime) é emitida somente quando executada no .NET 8 ou .NET 9. A implementação deteta as capacidades da plataforma em tempo de execução e permite o que é suportado sem configuração adicional.