diff --git a/src/Libraries/Microsoft.Extensions.Http.Diagnostics/Logging/HttpClientLoggingHttpClientBuilderExtensions.cs b/src/Libraries/Microsoft.Extensions.Http.Diagnostics/Logging/HttpClientLoggingHttpClientBuilderExtensions.cs index a79dd33dd60..b867a767c68 100644 --- a/src/Libraries/Microsoft.Extensions.Http.Diagnostics/Logging/HttpClientLoggingHttpClientBuilderExtensions.cs +++ b/src/Libraries/Microsoft.Extensions.Http.Diagnostics/Logging/HttpClientLoggingHttpClientBuilderExtensions.cs @@ -27,6 +27,8 @@ public static class HttpClientLoggingHttpClientBuilderExtensions /// The value of . /// /// All other loggers are removed - including the default one, registered via . + /// A lot of the information logged by this method (like bodies, methods, host, path, and duration) will be added as enrichment tags to the structured log. Make sure + /// you have a way of viewing structured logs in order to view this extra information. /// /// Argument is . public static IHttpClientBuilder AddExtendedHttpClientLogging(this IHttpClientBuilder builder) @@ -44,6 +46,8 @@ public static IHttpClientBuilder AddExtendedHttpClientLogging(this IHttpClientBu /// The value of . /// /// All other loggers are removed - including the default one, registered via . + /// A lot of the information logged by this method (like bodies, methods, host, path, and duration) will be added as enrichment tags to the structured log. Make sure + /// you have a way of viewing structured logs in order to view this extra information. /// /// Any of the arguments is . [DynamicDependency(DynamicallyAccessedMemberTypes.PublicProperties | DynamicallyAccessedMemberTypes.PublicParameterlessConstructor, typeof(LoggingOptions))] @@ -66,6 +70,8 @@ public static IHttpClientBuilder AddExtendedHttpClientLogging(this IHttpClientBu /// The value of . /// /// All other loggers are removed - including the default one, registered via . + /// A lot of the information logged by this method (like bodies, methods, host, path, and duration) will be added as enrichment tags to the structured log. Make sure + /// you have a way of viewing structured logs in order to view this extra information. /// /// Any of the arguments is . [DynamicDependency(DynamicallyAccessedMemberTypes.PublicProperties | DynamicallyAccessedMemberTypes.PublicParameterlessConstructor, typeof(LoggingOptions))] diff --git a/src/Libraries/Microsoft.Extensions.Http.Diagnostics/README.md b/src/Libraries/Microsoft.Extensions.Http.Diagnostics/README.md index 7739f0e50d3..780f407bb1b 100644 --- a/src/Libraries/Microsoft.Extensions.Http.Diagnostics/README.md +++ b/src/Libraries/Microsoft.Extensions.Http.Diagnostics/README.md @@ -1,6 +1,6 @@ # Microsoft.Extensions.Http.Diagnostics -Telemetry support for `HttpClient` that allows tracking latency and enriching and redacting log output. +Telemetry support for `HttpClient` that allows tracking latency and enriching and redacting log output for structured logs. ## Install the package @@ -24,9 +24,9 @@ Or directly in the C# project file: These components enable enriching and redacting `HttpClient` request logs. They remove built-it HTTP Client logging. -In order to use the redaction feature, you need to reference the `Microsoft.Extensions.Compliance.Redaction` package. +When using this package, some of the log properties are redacted by default (like full routes), which means that you will need to make sure that a redactor provider is registered in the Dependency Injection container. You can do this by making sure that you call `builder.Services.AddRedaction()` which requires a reference to the `Microsoft.Extensions.Compliance.Redaction` package. -The services can be registered using the following methods: +The http client logging services can be registered using the following methods: ```csharp public static IServiceCollection AddExtendedHttpClientLogging(this IServiceCollection services) @@ -55,6 +55,47 @@ builder.Services.AddHttpClientLogEnricher(); var host = builder.Build(); ``` +It is important to note that the `AddExtendedHttpClientLogging` method will add information to the logs using *enrichment*. This means that the information will be added as tags to the structured logs, but will not be visible in the log message that is printed by default in the console. To view the information, you will need to use a logging provider that supports structured logs. One quick and built-in way to do this, is to call `AddJsonConsole()` to your logging builder, which will print out the full structured logs to the console. Here is a quick sample that uses the `ExtendedHttpClientLogging()` method to automatically log all `HttpClient` request and response bodies, and then prints the full structured logs to the console: + +```csharp +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Logging; + +var services = new ServiceCollection(); + +services.AddLogging(o => o.SetMinimumLevel(LogLevel.Trace).AddJsonConsole()); // <-- Enable structured logging to the console + +// Adding default redactor provider to the DI container. This is required when using the AddExtendedHttpClientLogging() method. +services.AddRedaction(); + +services.AddHttpClient("foo") + .AddExtendedHttpClientLogging(o => + { + // Enable logging of request and response bodies: + o.LogBody = true; + + // We also need to specify the content types that we want to log: + o.ResponseBodyContentTypes.Add("application/json"); + }); + +var sp = services.BuildServiceProvider(); + +var client = sp.GetRequiredService().CreateClient("foo"); + +var response = await client.GetAsync(new Uri("https://httpbin.org/json")).ConfigureAwait(false); +``` + +By default, request and response routes are redacted for privacy reasons. You can change this behavior by making use of the `RequestPathParameterRedactionMode` option like: + +```csharp + .AddExtendedHttpClientLogging(o => +{ + //.. Other options + + o.RequestPathParameterRedactionMode = HttpRouteParameterRedactionMode.None; // <-- Disable redaction of request/response routes +}); +``` + You can also use the following extension methods to apply the logging to the specific `IHttpClientBuilder`: ```csharp