Skip to content

Commit 5aa8333

Browse files
authored
Merge pull request #146 from tomkerkhove/request-log-properties
Add RequestHost & RequestScheme to log properties
2 parents 7116569 + c350bce commit 5aa8333

File tree

4 files changed

+42
-5
lines changed

4 files changed

+42
-5
lines changed

README.md

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,7 @@ That's it! With the level bumped up a little you will see log output resembling:
8282

8383
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).
8484

85-
### Request logging <sup>`3.0.0-*`</sup>
85+
### Request logging <sup>`3.0.0`</sup>
8686

8787
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.
8888

@@ -159,6 +159,33 @@ During request processing, additional properties can be attached to the completi
159159

160160
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.
161161

162+
The following request information will be added as properties by default:
163+
164+
* `RequestMethod`
165+
* `RequestPath`
166+
* `StatusCode`
167+
* `Elapsed`
168+
169+
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()`:
170+
171+
```csharp
172+
app.UseSerilogRequestLogging(options =>
173+
{
174+
// Customize the message template
175+
options.MessageTemplate = "Handled {RequestPath}";
176+
177+
// Emit debug-level events instead of the defaults
178+
options.GetLevel = (httpContext, elapsed, ex) => LogEventLevel.Debug;
179+
180+
// Attach additional properties to the request completion event
181+
options.EnrichDiagnosticContext = (diagnosticContext, httpContext) =>
182+
{
183+
diagnosticContext.Set("RequestHost", httpContext.Request.Host.Value);
184+
diagnosticContext.Set("RequestScheme", httpContext.Request.Scheme);
185+
};
186+
});
187+
```
188+
162189
### Inline initialization
163190

164191
You can alternatively configure Serilog inline, in `BuildWebHost()`, using a delegate as shown below:

samples/EarlyInitializationSample/Startup.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
3131
// To use the default framework request logging instead, remove this line and set the "Microsoft"
3232
// level in appsettings.json to "Information".
3333
app.UseSerilogRequestLogging();
34-
34+
3535
app.UseRouting();
3636

3737
app.UseEndpoints(endpoints =>

src/Serilog.AspNetCore/AspNetCore/RequestLoggingMiddleware.cs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ class RequestLoggingMiddleware
2929
readonly RequestDelegate _next;
3030
readonly DiagnosticContext _diagnosticContext;
3131
readonly MessageTemplate _messageTemplate;
32+
readonly Action<IDiagnosticContext, HttpContext> _enrichDiagnosticContext;
3233
readonly Func<HttpContext, double, Exception, LogEventLevel> _getLevel;
3334
static readonly LogEventProperty[] NoProperties = new LogEventProperty[0];
3435

@@ -39,6 +40,7 @@ public RequestLoggingMiddleware(RequestDelegate next, DiagnosticContext diagnost
3940
_diagnosticContext = diagnosticContext ?? throw new ArgumentNullException(nameof(diagnosticContext));
4041

4142
_getLevel = options.GetLevel;
43+
_enrichDiagnosticContext = options.EnrichDiagnosticContext;
4244
_messageTemplate = new MessageTemplateParser().Parse(options.MessageTemplate);
4345
}
4446

@@ -79,6 +81,9 @@ bool LogCompletion(HttpContext httpContext, DiagnosticContextCollector collector
7981
if (!collector.TryComplete(out var collectedProperties))
8082
collectedProperties = NoProperties;
8183

84+
// Enrich diagnostic context
85+
_enrichDiagnosticContext?.Invoke(_diagnosticContext, httpContext);
86+
8287
// Last-in (correctly) wins...
8388
var properties = collectedProperties.Concat(new[]
8489
{

src/Serilog.AspNetCore/AspNetCore/RequestLoggingOptions.cs

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -35,16 +35,21 @@ public class RequestLoggingOptions
3535
public string MessageTemplate { get; set; }
3636

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

48+
/// <summary>
49+
/// A callback that can be used to set additional properties on the request completion event.
50+
/// </summary>
51+
public Action<IDiagnosticContext, HttpContext> EnrichDiagnosticContext { get; set; }
52+
4853
internal RequestLoggingOptions() { }
4954
}
50-
}
55+
}

0 commit comments

Comments
 (0)