Serilog.Enrichers.HttpRequestLogContext
1.0.0
Requires NuGet 3.3 or higher.
dotnet add package Serilog.Enrichers.HttpRequestLogContext --version 1.0.0
NuGet\Install-Package Serilog.Enrichers.HttpRequestLogContext -Version 1.0.0
<PackageReference Include="Serilog.Enrichers.HttpRequestLogContext" Version="1.0.0" />
paket add Serilog.Enrichers.HttpRequestLogContext --version 1.0.0
#r "nuget: Serilog.Enrichers.HttpRequestLogContext, 1.0.0"
// Install Serilog.Enrichers.HttpRequestLogContext as a Cake Addin #addin nuget:?package=Serilog.Enrichers.HttpRequestLogContext&version=1.0.0 // Install Serilog.Enrichers.HttpRequestLogContext as a Cake Tool #tool nuget:?package=Serilog.Enrichers.HttpRequestLogContext&version=1.0.0
Serilog.Enrichers.HttpRequestLogContext
A Serilog enricher to add properties to your log events scoped to a ASP.NET Core HttpRequest.
Getting started
Add the Serilog namespace to your startup or program C# file:
using Serilog;
Include the Http request log context enricher in your logger configuration:
builder.Host.UseSerilog((ctx, cfg) =>
cfg.Enrich.FromHttpRequestLogContext()
//rest of the configuration...
The FromHttpRequestLogContext()
enricher adds the properties present on the Serilog.Context.HttpRequestLogContext
, to all log events produced in the scope of an Http request.
The properties can be added and removed from the Http request log context using HttpRequestLogContext.PushProperty
:
HttpRequestLogContext.PushProperty("User", "Jonh_Doe");
HttpRequestLogContext.PushProperty("APIVersion", "1.0.1.239");
After the above code is executed, any log event written to any Serilog sink on the scope of the current Http request contain the properties User
and APIVersion
automatically.
Removing properties
The Serilog.Context.HttpRequestLogContext
is automatically cleared when the current Http request ends. However, properties can also be removed manually from the context by disposing the object returned by
the HttpRequestLogContext.PushProperty
method:
HttpRequestLogContext.PushProperty("A", 1);
Log.Information("Carries property A = 1");
using (HttpRequestLogContext.PushProperty("A", 2))
using (HttpRequestLogContext.PushProperty("B", 1))
{
Log.Information("Carries A = 2 and B = 1");
}
Log.Information("Carries property A = 1, again");
Pushing a property onto the Serilog.Context.HttpRequestLogContext
will override any existing properties with the same name, until the object returned from PushProperty()
is disposed, as the property A
in the example demonstrates.
Important: popping a property also pops all the properties pushed to the http context on top of it, as the next example demonstrates.
Log.Information("Carries no properties");
using (HttpRequestLogContext.PushProperty("A", 1))
{
HttpRequestLogContext.PushProperty("B", 1);
Log.Information("Carries A = 1 and B = 1");
}
Log.Information("Carries no properties, again");
Use case
When using Serilog on an ASP.NET Core project, it is very common to enrich the log on the controller methods, using the Serilog.Context.LogContext
. The problem here is that the properties added to the context will be scoped to the controller method only, and many log event on the current Http request will miss those properties.
builder.Host.UseSerilog((ctx, cfg) =>
cfg.Enrich.FromLogContext()
.WriteTo.Console(outputTemplate: "[{Timestamp:HH:mm:ss} {Level:u3}] [{$Location}] [{$PredictedTemp}] {Message:lj} {NewLine}{Exception}"));
[HttpGet]
public WeatherForecast Get(string location)
{
var forecast = new WeatherForecast
{
Date = DateTime.Now.AddDays(1),
TemperatureC = Random.Shared.Next(-20, 55),
Summary = Summaries[Random.Shared.Next(Summaries.Length)]
};
using (LogContext.PushProperty("Location", location))
using (LogContext.PushProperty("PredictedTemp", forecast.TemperatureC))
{
_logger.LogInformation("Weather forecast controller executing");
if (forecast.TemperatureC < -10)
throw new Exception("It's going to be freezing cold!");
return forecast;
}
}
It can be seen on the example above that ASP.NET Core logs many useful information, and these events are missing the the properties that are pushed on the controller. By using the Serilog.Context.HttpRequestLogContext
we can fix this issue easily.
builder.Host.UseSerilog((ctx, cfg) =>
cfg.Enrich.FromHttpRequestLogContext()
.WriteTo.Console(outputTemplate: "[{Timestamp:HH:mm:ss} {Level:u3}] [{$Location}] [{$PredictedTemp}] {Message:lj} {NewLine}{Exception}"));
[HttpGet]
public WeatherForecast Get(string location)
{
var forecast = new WeatherForecast
{
Date = DateTime.Now.AddDays(1),
TemperatureC = Random.Shared.Next(-20, 55),
Summary = Summaries[Random.Shared.Next(Summaries.Length)]
};
HttpRequestLogContext.PushProperty("Location", location);
HttpRequestLogContext.PushProperty("PredictedTemp", forecast.TemperatureC);
_logger.LogInformation("Returning weather forecast");
if (forecast.TemperatureC < -10)
throw new Exception("It's going to be freezing cold!");
return forecast;
}
All the events logged after the execution reaches the controller now include the properties that are pushed on the controller. These allows to easily inject our properties on the events that log the time that the request took, the http status code returned. In case there is any exception processing the Http request, the log will include the pushed properties as well.
Product | Versions Compatible and additional computed target framework versions. |
---|---|
.NET | net5.0 was computed. net5.0-windows was computed. net6.0 is compatible. net6.0-android was computed. net6.0-ios was computed. net6.0-maccatalyst was computed. net6.0-macos was computed. net6.0-tvos was computed. net6.0-windows was computed. net7.0 was computed. net7.0-android was computed. net7.0-ios was computed. net7.0-maccatalyst was computed. net7.0-macos was computed. net7.0-tvos was computed. net7.0-windows was computed. net8.0 was computed. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. |
.NET Core | netcoreapp2.0 was computed. netcoreapp2.1 was computed. netcoreapp2.2 was computed. netcoreapp3.0 was computed. netcoreapp3.1 was computed. |
.NET Standard | netstandard2.0 is compatible. netstandard2.1 was computed. |
.NET Framework | net461 was computed. net462 was computed. net463 was computed. net47 was computed. net471 was computed. net472 was computed. net48 was computed. net481 was computed. |
MonoAndroid | monoandroid was computed. |
MonoMac | monomac was computed. |
MonoTouch | monotouch was computed. |
Tizen | tizen40 was computed. tizen60 was computed. |
Xamarin.iOS | xamarinios was computed. |
Xamarin.Mac | xamarinmac was computed. |
Xamarin.TVOS | xamarintvos was computed. |
Xamarin.WatchOS | xamarinwatchos was computed. |
-
.NETStandard 2.0
- Microsoft.AspNetCore.Http (>= 2.2.2)
- Serilog (>= 3.1.0)
-
net6.0
- Microsoft.AspNetCore.Http (>= 2.2.2)
- Serilog (>= 3.1.0)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.
Version | Downloads | Last updated |
---|---|---|
1.0.0 | 1,773 | 11/27/2023 |
0.4.1-alpha | 119 | 11/28/2023 |
0.2.1-preview.0.1 | 72 | 11/27/2023 |