I would suggest using a simple middleware that you insert in the ASP .NET Core pipeline, to enrich Serilog's LogContext with the data you want, using the dependencies that you need, letting the ASP .NET Core dependency injection resolve the dependencies for you...
e.g. Assuming IUserDataService
is a service that you can use to get the data you need, to enrich the log, the middleware would look something like this:
public class UserDataLoggingMiddleware
{
private readonly RequestDelegate _next;
public UserDataLoggingMiddleware(RequestDelegate next)
{
_next = next;
}
public async Task Invoke(HttpContext context, IUserDataService userDataService)
{
var userData = await userDataService.GetAsync();
// Add user data to logging context
using (LogContext.PushProperty("UserData", userData))
{
await _next.Invoke(context);
}
}
}
LogContext.PushProperty
above is doing the enrichment, adding a property called UserData
to the log context of the current execution.
ASP .NET Core takes care of resolving IUserDataService
as long as you registered it in your Startup.ConfigureServices
.
Of course, for this to work, you'll have to:
1. Tell Serilog to enrich the log from the Log context, by calling Enrich.FromLogContext()
. e.g.
Log.Logger = new LoggerConfiguration()
.ReadFrom.Configuration(Configuration)
.Enrich.FromLogContext() // <<======================
.WriteTo.Console(
outputTemplate: "[{Timestamp:HH:mm:ss} {Level:u3}] {Message:lj} " +
"{Properties:j}{NewLine}{Exception}")
.CreateLogger();
2. Add your middleware to the pipeline, in your Startup.Configure
. e.g.
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
// ...
app.UseMiddleware<UserDataLoggingMiddleware>();
// ...
app.UseMvc();
}
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…