I have this Serilog configuration in program.cs
public class Program { public static IConfiguration Configuration { get; } = new ConfigurationBuilder() .SetBasePath(Directory.GetCurrentDirectory()) .AddJsonFile("appsettings.json", optional: false, reloadOnChange: true) .AddJsonFile($"appsettings.{Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT") ?? "Production"}.json", optional: true) .Build(); public static void Main(string[] args) { Log.Logger = new LoggerConfiguration() .MinimumLevel.Override("Microsoft", LogEventLevel.Warning) .MinimumLevel.Override("System", LogEventLevel.Warning) .WriteTo.MSSqlServer(Configuration.GetConnectionString("DefaultConnection"), "dbo.Log") .Enrich.WithThreadId() .Enrich.WithProperty("Version", "1.0.0") .CreateLogger(); try { BuildWebHost(args).Run(); } catch (Exception ex) { Log.Fatal(ex, "Host terminated unexpectedly"); } finally { Log.CloseAndFlush(); } } public static IWebHost BuildWebHost(string[] args) => WebHost.CreateDefaultBuilder(args) .UseStartup<Startup>() .UseSerilog() .Build(); }
Now i want to add HttpContext.Current.User.Identity.Name
into all log messages.
I tried to create new Enrich class following documentation https://github.com/serilog/serilog/wiki/Configuration-Basics#enrichers
class UsernameEnricher : ILogEventEnricher { public void Enrich(LogEvent logEvent, ILogEventPropertyFactory propertyFactory, HttpContext httpContext) { logEvent.AddPropertyIfAbsent(propertyFactory.CreateProperty( "Username", httpContext.User.Identity.Name)); } }
But there is conflict with ILogEventEnricher which does not know HttpContext.
I also tried to install Nuget package Serilog.Web.Classic which contains Username Enricher, but there is conflict between target framework .Net Framework and .Net Core therefore i cannot use this plugin.
Any idea ?
You can create a middleware to put required property to LogContext.
public class LogUserNameMiddleware { private readonly RequestDelegate next; public LogUserNameMiddleware(RequestDelegate next) { this.next = next; } public Task Invoke(HttpContext context) { LogContext.PushProperty("UserName", context.User.Identity.Name); return next(context); } }
Also you need to add the following to your logger configuration:
.Enrich.FromLogContext()
In Startup add the middleware LogUserNameMiddleware
, and also note that the middleware should be added after UserAuthentication
, in order to have context.User.Identity
initialized
e.g.
app.UseAuthentication(); app.UseMiddleware<LogUserNameMiddleware>();
If you are using Serilog.AspNetCore it's very easy to add authentication/user properties.
app.UseSerilogRequestLogging(options => { options.EnrichDiagnosticContext = PushSeriLogProperties; }); public void PushSeriLogProperties(IDiagnosticContext diagnosticContext, HttpContext httpContext) { diagnosticContext.Set("SomePropertyName", httpContext.User...); }
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With