Login de cliente HTTP em .NET

Quando constrói aplicações que fazem pedidos HTTP, o registo estruturado ajuda-o a monitorizar, resolver problemas e analisar o tráfego de saída. A AddExtendedHttpClientLogging extensão oferece registo melhorado para todos os clientes HTTP criados com IHttpClientFactory, com suporte incorporado para:

  • Registo configurável - Controla o que é registado (cabeçalhos, corpo, parâmetros de consulta, parâmetros de rota)
  • Redação de dados - Aplicar políticas de classificação e redação de dados para privacidade e conformidade
  • Enriquecimento de registos - Adicionar contexto personalizado aos registos de pedidos HTTP
  • Sobrecarga mínima - Funcionalidades de opt-in com predefinições conscientes do desempenho

Ative o registo avançado do cliente HTTP chamando o AddExtendedHttpClientLogging método de extensão. Isto substitui o logger HTTP cliente predefinido por um logger estendido que suporta configurações finas e funcionalidades de conformidade de dados.

Adicionar o pacote

dotnet add package Microsoft.Extensions.Http.Diagnostics

Ou, se você estiver usando o SDK do .NET 10+:

dotnet package add Microsoft.Extensions.Http.Diagnostics

Para obter mais informações, consulte dotnet package add ou Manage package dependencies in .NET applications.

Ativar o registo do cliente HTTP

Para adicionar um login de cliente HTTP melhorado à sua aplicação, chame o método de extensão AddExtendedHttpClientLogging ao configurar os seus serviços:

using Microsoft.Extensions.DependencyInjection;

HostApplicationBuilder builder = Host.CreateApplicationBuilder(args);

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

// Add enhanced HTTP client logging
builder.Services.AddExtendedHttpClientLogging();

// Add your HTTP clients
builder.Services.AddHttpClient<MyApiClient>();

using IHost host = builder.Build();

await host.RunAsync();

Este registo adiciona um logger melhorado a todos os clientes HTTP criados através de IHttpClientFactory, substituindo o logger predefinido por um que suporta configuração avançada.

Importante

AddExtendedHttpClientLogging() remove todos os outros loggers, incluindo o padrão registado via AddDefaultLogger(). Isto garante um comportamento consistente de registo em todos os clientes HTTP.

Importante

Deve registar os serviços de censura ligando para AddRedaction a partir do pacote Microsoft.Extensions.Compliance.Redaction. A funcionalidade de registo do cliente HTTP oculta informações sensíveis por defeito (como parâmetros de rota) e requer um fornecedor redator no contentor de injeção de dependências.

Aplicar registo a clientes HTTP específicos

Também pode aplicar registo melhorado a clientes HTTP nomeados ou tipados específicos usando métodos de extensão IHttpClientBuilder.

HostApplicationBuilder builder = Host.CreateApplicationBuilder(args);

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

// Apply to a named client
builder.Services.AddHttpClient("MyNamedClient")
    .AddExtendedHttpClientLogging();

// Apply to a typed client with configuration
builder.Services.AddHttpClient<MyApiClient>()
    .AddExtendedHttpClientLogging(options =>
    {
        options.LogBody = true;
        options.ResponseBodyContentTypes.Add("application/json");
    });

using IHost host = builder.Build();

await host.RunAsync();    

Ao usar as IHttpClientBuilder sobrecargas, o registo é aplicado apenas a esse cliente específico, não globalmente.

Visualização de dados de registos enriquecidos

O logging melhorado do cliente HTTP adiciona informação aos logs usando enriquecimento, o que significa que os dados são adicionados como etiquetas a logs estruturados em vez de à mensagem no console. Para visualizar a informação enriquecida, utilize um fornecedor de registos que suporte registos estruturados.

Para testes rápidos, use AddJsonConsole para imprimir registos estruturados na consola:

HostApplicationBuilder builder = Host.CreateApplicationBuilder(args);

builder.Logging.AddJsonConsole();

builder.Services.AddRedaction();

builder.Services.AddHttpClient("MyClient")
    .AddExtendedHttpClientLogging(options =>
    {
        options.LogBody = true;
        options.ResponseBodyContentTypes.Add("application/json");
    });

Para cenários de produção, considere usar fornecedores de registo estruturado como Application Insights, Seq ou Elasticsearch, que podem consultar e visualizar os dados enriquecidos da etiqueta.

Configurar opções de registo

Configura o login do cliente HTTP através da LoggingOptions classe usando o padrão de opções. Pode configurar opções no código ou associá-las a partir da configuração (por exemplo, appsettings.json).

Configurar com um delegado

builder.Services.AddExtendedHttpClientLogging(options =>
{
    // Log request headers with data classification
    options.RequestHeadersDataClasses.Add("User-Agent", DataClassification.None);
    options.RequestHeadersDataClasses.Add("Authorization", DataClassification.Unknown);

    // Log response headers
    options.ResponseHeadersDataClasses.Add("Content-Type", DataClassification.None);

    // Enable request/response body logging (use carefully in production)
    options.LogBody = true;
    options.BodySizeLimit = 4096; // Limit to 4KB
    options.RequestBodyContentTypes.Add("application/json");
    options.ResponseBodyContentTypes.Add("application/json");
});

Configurar a partir de appsettings.json

{
  "HttpClientLogging": {
    "LogRequestStart": false,
    "LogBody": false,
    "BodySizeLimit": 32768,
    "BodyReadTimeout": "00:00:01",
    "RequestHeadersDataClasses": {
      "User-Agent": "None",
      "Content-Type": "None"
    },
    "ResponseHeadersDataClasses": {
      "Content-Type": "None"
    },
    "RequestPathLoggingMode": "Formatted",
    "RequestPathParameterRedactionMode": "Strict"
  }
}
builder.Services.AddExtendedHttpClientLogging(
    builder.Configuration.GetSection("HttpClientLogging"));

Opções de configuração

A LoggingOptions classe oferece as seguintes opções de configuração:

Opções básicas de registo

Opção Tipo Predefinido Description
LogRequestStart bool false Quando true, regista o pedido antes do início do processamento. Quando false, regista uma única entrada com dados de pedido e resposta.
LogBody bool false Permite o registo dos corpos de pedidos e respostas HTTP. Aviso: Evite ativar em produção, pois pode divulgar informações sensíveis.
BodySizeLimit int 32.768 (≈32KB) Número máximo de bytes a ler do corpo do pedido ou resposta. Mantenha abaixo dos 85.000 bytes para evitar uma grande alocação de pilhas de objetos .
BodyReadTimeout TimeSpan 1 segundo Tempo máximo de espera ao ler o pedido ou o corpo da resposta. Deve ser entre 1 milissegundo e 1 minuto.
RequestBodyContentTypes ISet<string> Vazio Os tipos de conteúdo dos pedidos HTTP são considerados texto e elegíveis para serialização.
ResponseBodyContentTypes ISet<string> Vazio Tipos de conteúdo de resposta HTTP considerados texto e elegíveis para serialização.

Registo de cabeçalhos e parâmetros de consulta

Opção Tipo Predefinido Description
RequestHeadersDataClasses IDictionary<string, DataClassification> Vazio Cabeçalhos de pedido HTTP para registar com as suas classificações de dados para redação. Se estiver vazio, nenhum cabeçalho de pedido é registado.
ResponseHeadersDataClasses IDictionary<string, DataClassification> Vazio Cabeçalhos de resposta HTTP para registar com as suas classificações de dados para redação. Se estiver vazia, nenhum cabeçalho de resposta é registado.
RequestQueryParametersDataClasses IDictionary<string, DataClassification> Vazio Parâmetros de consulta de requisição HTTP para registar com as respetivas classificações de dados. Se estiver vazio, nenhum parâmetro de consulta é registado. Funcionalidade experimental.
LogContentHeaders bool false Permitir o registo dos cabeçalhos de conteúdo HTTP (por exemplo, Content-Type). Ativar apenas se os cabeçalhos de conteúdo estiverem em RequestHeadersDataClasses ou ResponseHeadersDataClasses. Funcionalidade experimental.

Registo de parâmetros de caminho e rota

Opção Tipo Predefinido Description
RequestPathLoggingMode OutgoingPathLoggingMode Formatted Como registar o caminho do pedido HTTP de saída. Aplicado apenas quando RequestPathParameterRedactionMode não é None.
RequestPathParameterRedactionMode HttpRouteParameterRedactionMode Strict Como editar parâmetros de caminho em pedidos HTTP de saída.
RouteParameterDataClasses IDictionary<string, DataClassification> Vazio Parâmetros de rota para redigir com as respetivas classificações de dados.

Adicionar enriquecedores de logs

Os enriquecedores de logs do cliente HTTP permitem-lhe adicionar informação contextual personalizada aos logs do cliente HTTP com base no pedido, resposta e quaisquer exceções. Ao contrário dos enriquecedores de logs de uso geral, os enriquecedores de clientes HTTP direcionam especificamente os pedidos HTTP de saída e têm acesso a contextos específicos de HTTP.

Aqui está um exemplo rápido:

public class CustomHttpLogEnricher : IHttpClientLogEnricher
{
    public void Enrich(IEnrichmentTagCollector collector,
        HttpRequestMessage request, HttpResponseMessage? response, Exception? exception)
    {
        // Add tags based on the exception (if available)
        if (exception is not null)
        {
            collector.Add("error_type", exception.GetType().Name);
        }
    }
}

// Register the enricher
builder.Services.AddHttpClientLogEnricher<CustomHttpLogEnricher>();

Para informações detalhadas sobre a criação e utilização de enriquecedores de logs de cliente HTTP, incluindo boas práticas e cenários avançados, consulte HTTP client log enricher.

Classificação e redação de dados

O registo de clientes HTTP integra-se com as funcionalidades de redação e classificação de dados para proteger informações sensíveis. Quando especifica um DataClassification para cabeçalhos, parâmetros de consulta ou parâmetros de rota, o sistema de censura aplica a redação apropriada com base nos redatores que configurou.

Exemplo: Redigir cabeçalhos sensíveis

using Microsoft.Extensions.Compliance.Classification;

builder.Services.AddExtendedHttpClientLogging(options =>
{
    // Public headers - no redaction
    options.RequestHeadersDataClasses.Add("User-Agent", DataClassification.None);
    options.RequestHeadersDataClasses.Add("Content-Type", DataClassification.None);

    // Sensitive headers - apply redaction
    options.RequestHeadersDataClasses.Add("Authorization", DataClassification.Unknown);
    options.RequestHeadersDataClasses.Add("X-API-Key", DataClassification.Unknown);
});

Para mais informações sobre a configuração dos redatores, consulte Redação de dados em .NET.

Redação de parâmetros de caminho e rota

Por defeito, o registo do cliente HTTP redige os caminhos de pedido e resposta para proteger a privacidade. Ao registar caminhos de pedido HTTP, pode controlar como os parâmetros de rota são redigidos usando a opção RequestPathParameterRedactionMode:

Modo Description Example
None Sem redação, o caminho completo está registado /api/users/12345/orders/67890
Strict Todos os parâmetros do caminho estão redigidos /api/users/{userId}/orders/{orderId}
Loose Apenas os parâmetros em RouteParameterDataClasses estão redigidos /api/users/12345/orders/{orderId}

A RequestPathLoggingMode opção controla o formato do caminho registado:

Modo Description Example
Formatted Utiliza o formato de modelo de rota com nomes de parâmetros /api/users/{userId}/orders/{orderId}
Structured Registos de percurso e parâmetros separadamente Caminho: /api/users/*/orders/*, Params: {userId, orderId}

Exemplo: Desativar a redação de caminhos

Para registar caminhos completos e não censurados (por exemplo, em ambientes de desenvolvimento), defina RequestPathParameterRedactionMode para None:

builder.Services.AddExtendedHttpClientLogging(options =>
{
    // Disable redaction of request/response paths
    options.RequestPathParameterRedactionMode = HttpRouteParameterRedactionMode.None;
});

Atenção

Desativar a ocultação de caminhos pode expor informações sensíveis nos logs. Uso HttpRouteParameterRedactionMode.None apenas no desenvolvimento ou quando certos caminhos não contêm dados sensíveis.

Considerações sobre desempenho

O registo melhorado de clientes HTTP foi concebido a pensar no desempenho, mas existem compensações a considerar.

  • Registo de Dados: Ativar LogBody adiciona sobrecarga para a bufferização e leitura dos conteúdos dos pedidos e das respostas. Usar BodySizeLimit e BodyReadTimeout para controlar o uso de recursos.
  • Registo de cabeçalhos: Só os cabeçalhos de log que precisas. RequestHeadersDataClasses e ResponseHeadersDataClasses vazios evitam a sobrecarga do processamento de cabeçalhos.
  • Enriquecedores: Cada enriquecedor registado é invocado para cada solicitação. Mantenha a lógica de enriquecimento leve.
  • Redação: A classificação e redação dos dados acrescentam sobrecarga mínima, mas escalam com o número de itens classificados.

Sugestão

Em ambientes de produção, comece com registo mínimo (sem corpo, cabeçalhos limitados) e ative registos adicionais apenas para resolução de problemas.

Consulte também