diff --git a/README.md b/README.md index 4c324f6..860fe95 100644 --- a/README.md +++ b/README.md @@ -82,7 +82,7 @@ That's it! With the level bumped up a little you will see log output resembling: A more complete example, showing `appsettings.json` configuration, can be found in [the sample project here](https://github.com/serilog/serilog-aspnetcore/tree/dev/samples/EarlyInitializationSample). -### Request logging `3.0.0-*` +### Request logging The package includes middleware for smarter HTTP request logging. The default request logging implemented by ASP.NET Core is noisy, with multiple events emitted per request. The included middleware condenses these into a single event that carries method, path, status code, and timing information. @@ -159,6 +159,33 @@ During request processing, additional properties can be attached to the completi This pattern has the advantage of reducing the number of log events that need to be constructed, transmitted, and stored per HTTP request. Having many properties on the same event can also make correlation of request details and other data easier. +The following request information will be added as properties by default: + +* `RequestMethod` +* `RequestPath` +* `StatusCode` +* `Elapsed` + +You can modify the message template used for request completion events, add additional properties, or change the event level, using the `options` callback on `UseSerilogRequestLogging()`: + +```csharp +app.UseSerilogRequestLogging(options => +{ + // Customize the message template + options.MessageTemplate = "Handled {RequestPath}"; + + // Emit debug-level events instead of the defaults + options.GetLevel = (httpContext, elapsed, ex) => LogEventLevel.Debug; + + // Attach additional properties to the request completion event + options.EnrichDiagnosticContext = (diagnosticContext, httpContext) => + { + diagnosticContext.Set("RequestHost", httpContext.Request.Host.Value); + diagnosticContext.Set("RequestScheme", httpContext.Request.Scheme); + }; +}); +``` + ### Inline initialization You can alternatively configure Serilog inline, in `BuildWebHost()`, using a delegate as shown below: @@ -176,7 +203,7 @@ If this method is used, `Log.Logger` is assigned implicitly, and closed when the A complete example, showing this approach, can be found in [the _InlineIntializationSample_ project](https://github.com/serilog/serilog-aspnetcore/tree/dev/samples/InlineInitializationSample). -### Enabling `Microsoft.Extensions.Logging.ILoggerProvider`s `3.0.0-*` +### Enabling `Microsoft.Extensions.Logging.ILoggerProvider`s Serilog sends events to outputs called _sinks_, that implement Serilog's `ILogEventSink` interface, and are added to the logging pipeline using `WriteTo`. _Microsoft.Extensions.Logging_ has a similar concept called _providers_, and these implement `ILoggerProvider`. Providers are what the default logging configuration creates under the hood through methods like `AddConsole()`. diff --git a/samples/EarlyInitializationSample/Startup.cs b/samples/EarlyInitializationSample/Startup.cs index 502c133..25d0c75 100644 --- a/samples/EarlyInitializationSample/Startup.cs +++ b/samples/EarlyInitializationSample/Startup.cs @@ -31,7 +31,7 @@ public void Configure(IApplicationBuilder app, IWebHostEnvironment env) // To use the default framework request logging instead, remove this line and set the "Microsoft" // level in appsettings.json to "Information". app.UseSerilogRequestLogging(); - + app.UseRouting(); app.UseEndpoints(endpoints => diff --git a/src/Serilog.AspNetCore/AspNetCore/RequestLoggingMiddleware.cs b/src/Serilog.AspNetCore/AspNetCore/RequestLoggingMiddleware.cs index 954b326..e6c17f1 100644 --- a/src/Serilog.AspNetCore/AspNetCore/RequestLoggingMiddleware.cs +++ b/src/Serilog.AspNetCore/AspNetCore/RequestLoggingMiddleware.cs @@ -29,6 +29,7 @@ class RequestLoggingMiddleware readonly RequestDelegate _next; readonly DiagnosticContext _diagnosticContext; readonly MessageTemplate _messageTemplate; + readonly Action _enrichDiagnosticContext; readonly Func _getLevel; static readonly LogEventProperty[] NoProperties = new LogEventProperty[0]; @@ -39,6 +40,7 @@ public RequestLoggingMiddleware(RequestDelegate next, DiagnosticContext diagnost _diagnosticContext = diagnosticContext ?? throw new ArgumentNullException(nameof(diagnosticContext)); _getLevel = options.GetLevel; + _enrichDiagnosticContext = options.EnrichDiagnosticContext; _messageTemplate = new MessageTemplateParser().Parse(options.MessageTemplate); } @@ -76,6 +78,9 @@ bool LogCompletion(HttpContext httpContext, DiagnosticContextCollector collector if (!logger.IsEnabled(level)) return false; + // Enrich diagnostic context + _enrichDiagnosticContext?.Invoke(_diagnosticContext, httpContext); + if (!collector.TryComplete(out var collectedProperties)) collectedProperties = NoProperties; diff --git a/src/Serilog.AspNetCore/AspNetCore/RequestLoggingOptions.cs b/src/Serilog.AspNetCore/AspNetCore/RequestLoggingOptions.cs index 3a4127a..327e468 100644 --- a/src/Serilog.AspNetCore/AspNetCore/RequestLoggingOptions.cs +++ b/src/Serilog.AspNetCore/AspNetCore/RequestLoggingOptions.cs @@ -35,16 +35,21 @@ public class RequestLoggingOptions public string MessageTemplate { get; set; } /// - /// Gets or sets the function returning the based on the , the number of + /// A function returning the based on the , the number of /// elapsed milliseconds required for handling the request, and an if one was thrown. /// The default behavior returns when the response status code is greater than 499 or if the /// is not null. /// /// - /// The function returning the . + /// A function returning the . /// public Func GetLevel { get; set; } + /// + /// A callback that can be used to set additional properties on the request completion event. + /// + public Action EnrichDiagnosticContext { get; set; } + internal RequestLoggingOptions() { } } -} \ No newline at end of file +} diff --git a/src/Serilog.AspNetCore/Serilog.AspNetCore.csproj b/src/Serilog.AspNetCore/Serilog.AspNetCore.csproj index ed44508..5c5c3f7 100644 --- a/src/Serilog.AspNetCore/Serilog.AspNetCore.csproj +++ b/src/Serilog.AspNetCore/Serilog.AspNetCore.csproj @@ -2,7 +2,7 @@ Serilog support for ASP.NET Core logging - 3.1.0 + 3.2.0 Microsoft;Serilog Contributors netstandard2.0 true