Skip to content

3.2.0 Release #150

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 14 commits into from
Nov 12, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 29 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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 <sup>`3.0.0-*`</sup>
### 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.

Expand Down Expand Up @@ -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:
Expand All @@ -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 <sup>`3.0.0-*`</sup>
### 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()`.

Expand Down
2 changes: 1 addition & 1 deletion samples/EarlyInitializationSample/Startup.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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 =>
Expand Down
5 changes: 5 additions & 0 deletions src/Serilog.AspNetCore/AspNetCore/RequestLoggingMiddleware.cs
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ class RequestLoggingMiddleware
readonly RequestDelegate _next;
readonly DiagnosticContext _diagnosticContext;
readonly MessageTemplate _messageTemplate;
readonly Action<IDiagnosticContext, HttpContext> _enrichDiagnosticContext;
readonly Func<HttpContext, double, Exception, LogEventLevel> _getLevel;
static readonly LogEventProperty[] NoProperties = new LogEventProperty[0];

Expand All @@ -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);
}

Expand Down Expand Up @@ -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;

Expand Down
11 changes: 8 additions & 3 deletions src/Serilog.AspNetCore/AspNetCore/RequestLoggingOptions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -35,16 +35,21 @@ public class RequestLoggingOptions
public string MessageTemplate { get; set; }

/// <summary>
/// Gets or sets the function returning the <see cref="LogEventLevel"/> based on the <see cref="HttpContext"/>, the number of
/// A function returning the <see cref="LogEventLevel"/> based on the <see cref="HttpContext"/>, the number of
/// elapsed milliseconds required for handling the request, and an <see cref="Exception" /> if one was thrown.
/// The default behavior returns <see cref="LogEventLevel.Error"/> when the response status code is greater than 499 or if the
/// <see cref="Exception"/> is not null.
/// </summary>
/// <value>
/// The function returning the <see cref="LogEventLevel"/>.
/// A function returning the <see cref="LogEventLevel"/>.
/// </value>
public Func<HttpContext, double, Exception, LogEventLevel> GetLevel { get; set; }

/// <summary>
/// A callback that can be used to set additional properties on the request completion event.
/// </summary>
public Action<IDiagnosticContext, HttpContext> EnrichDiagnosticContext { get; set; }

internal RequestLoggingOptions() { }
}
}
}
2 changes: 1 addition & 1 deletion src/Serilog.AspNetCore/Serilog.AspNetCore.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

<PropertyGroup>
<Description>Serilog support for ASP.NET Core logging</Description>
<VersionPrefix>3.1.0</VersionPrefix>
<VersionPrefix>3.2.0</VersionPrefix>
<Authors>Microsoft;Serilog Contributors</Authors>
<TargetFrameworks>netstandard2.0</TargetFrameworks>
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
Expand Down