How can I get the current HttpContext in a SeriLog Sink?
I have been struggling trying to do the same and I finally found a proper solution.
Do not add the enricher when creating the Logger. You will have to add the enricher in the middleware where you can access the IServiceProvider
. The key is that LogContext
has a method, Push
, that can add an enricher:
public async Task Invoke(HttpContext httpContext)
{
IServiceProvider serviceProvider = httpContext.RequestServices;
using (LogContext.Push(new LogEnricher(serviceProvider))) {
await _next(httpContext);
}
}
In the ConfigureServices
, I add a services.AddScoped<HttpContextToLog>()
call.
Then, I populate the HttpContextToLog
object in several places, accessing it like this:
HttpContextToLog contextToLog = _serviceProvider.GetService<HttpContextToLog>();
in the Enrich
method, in an IActionFilter
, in an IPageFilter
, etc.
UPDATE I think you may want to look at this article : http://mylifeforthecode.github.io/enriching-serilog-output-with-httpcontext-information-in-asp-net-core/
The idea is to register a custom middleware that will add all the contextual information to the current LogContext
during the request.
For it to work you must configure your logger with
Log.Logger = new LoggerConfiguration()
// snip ....MinimumLevel.Debug()
.Enrich.FromLogContext()
// snip ...
.CreateLogger();
This article by Nicholas Blumhardt may also help : https://blog.getseq.net/smart-logging-middleware-for-asp-net-core/
WARNING - Solution below does not work in this case
The solution below cannot work if the logger is registered early (in Program.Main() )
First of all, if you want to add extra information attached to the logged event, I believe what you want is an Enricher.
You could then :
- Register IHttpContextAccessor into your ServiceCollection (for instance, using
AddHttpContextAccessor()
) :services.AddHttpContextAccessor();
- Create an implementation of
ILogEventEnricher
that acceptsIHttpContextAccessor
in its constructor - When configuring your logger, inject
IHttpContextAccessor
(by adding an argument of typeIHttpContextAccessor
toStartup.Configure()
- Add this enricher to your logger
The enricher could look something like https://github.com/serilog-web/classic/blob/master/src/SerilogWeb.Classic/Classic/Enrichers/ClaimValueEnricher.cs .
And you would configure your logger like this :
var logger = new LoggerConfiguration()
.EnrichWith(new MyEnricher(contextAccessor))
.WriteTo.Whatever()
.CreateLogger();