Note
Access to this page requires authorization. You can try signing in or changing directories.
Access to this page requires authorization. You can try changing directories.
When you build applications that make HTTP requests, structured logging helps you monitor, troubleshoot, and analyze outgoing traffic. The AddExtendedHttpClientLogging extension provides enhanced logging for all HTTP clients created with IHttpClientFactory, with built-in support for:
- Configurable logging - Control what gets logged (headers, body, query parameters, route parameters)
- Data redaction - Apply data classification and redaction policies for privacy and compliance
- Log enrichment - Add custom context to HTTP request logs
- Minimal overhead - Opt-in features with performance-conscious defaults
Enable enhanced HTTP client logging by calling the AddExtendedHttpClientLogging extension method. This replaces the default HTTP client logger with an extended logger that supports fine-grained configuration and data compliance features.
Add the package
dotnet add package Microsoft.Extensions.Http.Diagnostics
Or, if you're using .NET 10+ SDK:
dotnet package add Microsoft.Extensions.Http.Diagnostics
For more information, see dotnet package add or Manage package dependencies in .NET applications.
Enable HTTP client logging
To add enhanced HTTP client logging to your application, call the AddExtendedHttpClientLogging extension method when configuring your services:
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();
This registration adds an enhanced logger to all HTTP clients created through IHttpClientFactory, replacing the default logger with one that supports advanced configuration.
Important
AddExtendedHttpClientLogging() removes all other loggers, including the default one registered via AddDefaultLogger(). This ensures consistent logging behavior across all HTTP clients.
Important
You must register redaction services by calling AddRedaction from the Microsoft.Extensions.Compliance.Redaction package. The HTTP client logging feature redacts sensitive information by default (such as route parameters) and requires a redactor provider in the dependency injection container.
Apply logging to specific HTTP clients
You can also apply enhanced logging to specific named or typed HTTP clients using the IHttpClientBuilder extension methods:
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();
When using the IHttpClientBuilder overloads, logging is applied only to that specific client, not globally.
Viewing enriched log data
Enhanced HTTP client logging adds information to logs using enrichment, which means data is added as tags to structured logs rather than to the console message. To view the enriched information, use a logging provider that supports structured logs.
For quick testing, use AddJsonConsole to print structured logs to the console:
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");
});
For production scenarios, consider using structured logging providers like Application Insights, Seq, or Elasticsearch that can query and visualize the enriched tag data.
Configure logging options
You configure HTTP client logging through the LoggingOptions class using the standard options pattern. You can configure options in code or bind them from configuration (for example, appsettings.json).
Configure with a delegate
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");
});
Configure from 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"));
Configuration options
The LoggingOptions class provides the following configuration options:
Basic logging options
| Option | Type | Default | Description |
|---|---|---|---|
LogRequestStart |
bool |
false |
When true, logs the request before processing starts. When false, logs a single entry with both request and response data. |
LogBody |
bool |
false |
Enables logging of HTTP request and response bodies. Warning: Avoid enabling in production as it might leak sensitive information. |
BodySizeLimit |
int |
32,768 (≈32KB) | Maximum number of bytes to read from request or response body. Keep below 85,000 bytes to avoid large object heap allocation. |
BodyReadTimeout |
TimeSpan |
1 second | Maximum time to wait when reading request or response body. Must be between 1 millisecond and 1 minute. |
RequestBodyContentTypes |
ISet<string> |
Empty | HTTP request content types considered text and eligible for serialization. |
ResponseBodyContentTypes |
ISet<string> |
Empty | HTTP response content types considered text and eligible for serialization. |
Header and query parameter logging
| Option | Type | Default | Description |
|---|---|---|---|
RequestHeadersDataClasses |
IDictionary<string, DataClassification> |
Empty | HTTP request headers to log with their data classifications for redaction. If empty, no request headers are logged. |
ResponseHeadersDataClasses |
IDictionary<string, DataClassification> |
Empty | HTTP response headers to log with their data classifications for redaction. If empty, no response headers are logged. |
RequestQueryParametersDataClasses |
IDictionary<string, DataClassification> |
Empty | HTTP request query parameters to log with their data classifications. If empty, no query parameters are logged. Experimental feature. |
LogContentHeaders |
bool |
false |
Enable logging of HTTP content headers (for example, Content-Type). Only enable if content headers are in RequestHeadersDataClasses or ResponseHeadersDataClasses. Experimental feature. |
Path and route parameter logging
| Option | Type | Default | Description |
|---|---|---|---|
RequestPathLoggingMode |
OutgoingPathLoggingMode |
Formatted |
How to log the outgoing HTTP request path. Applied only when RequestPathParameterRedactionMode is not None. |
RequestPathParameterRedactionMode |
HttpRouteParameterRedactionMode |
Strict |
How to redact path parameters in outgoing HTTP requests. |
RouteParameterDataClasses |
IDictionary<string, DataClassification> |
Empty | Route parameters to redact with their corresponding data classifications. |
Add log enrichers
HTTP client log enrichers allow you to add custom contextual information to HTTP client logs based on the request, response, and any exceptions. Unlike general-purpose log enrichers, HTTP client enrichers specifically target outgoing HTTP requests and have access to HTTP-specific context.
Here's a quick example:
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>();
For detailed information on creating and using HTTP client log enrichers, including best practices and advanced scenarios, see HTTP client log enricher.
Data classification and redaction
HTTP client logging integrates with the data redaction and data classification features to protect sensitive information. When you specify a DataClassification for headers, query parameters, or route parameters, the redaction system applies appropriate redaction based on your configured redactors.
Example: Redacting sensitive headers
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);
});
For more information about configuring redactors, see Data redaction in .NET.
Path and route parameter redaction
By default, HTTP client logging redacts request and response paths to protect privacy. When logging HTTP request paths, you can control how route parameters are redacted using the RequestPathParameterRedactionMode option:
| Mode | Description | Example |
|---|---|---|
None |
No redaction, full path is logged | /api/users/12345/orders/67890 |
Strict |
All path parameters are redacted | /api/users/{userId}/orders/{orderId} |
Loose |
Only parameters in RouteParameterDataClasses are redacted |
/api/users/12345/orders/{orderId} |
The RequestPathLoggingMode option controls the format of the logged path:
| Mode | Description | Example |
|---|---|---|
Formatted |
Uses route template format with parameter names | /api/users/{userId}/orders/{orderId} |
Structured |
Logs path and parameters separately | Path: /api/users/*/orders/*, Params: {userId, orderId} |
Example: Disable path redaction
To log full, unredacted paths (for example, in development environments), set RequestPathParameterRedactionMode to None:
builder.Services.AddExtendedHttpClientLogging(options =>
{
// Disable redaction of request/response paths
options.RequestPathParameterRedactionMode = HttpRouteParameterRedactionMode.None;
});
Caution
Disabling path redaction might expose sensitive information in logs. Only use HttpRouteParameterRedactionMode.None in development or when you're certain paths don't contain sensitive data.
Performance considerations
Enhanced HTTP client logging is designed with performance in mind, but there are trade-offs to consider:
- Body logging: Enabling
LogBodyadds overhead for buffering and reading request/response bodies. UseBodySizeLimitandBodyReadTimeoutto control resource usage. - Header logging: Only log headers you need. Empty
RequestHeadersDataClassesandResponseHeadersDataClassesavoid header processing overhead. - Enrichers: Each registered enricher is called for every request. Keep enricher logic lightweight.
- Redaction: Data classification and redaction add minimal overhead but scale with the number of classified items.
Tip
In production environments, start with minimal logging (no body, limited headers) and enable additional logging only for troubleshooting.