Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Add Username into Serilog

Tags:

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 ?

like image 494
Muflix Avatar asked Jul 10 '18 09:07

Muflix


2 Answers

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>(); 
like image 129
Alex Riabov Avatar answered Sep 20 '22 14:09

Alex Riabov


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...);     } 
like image 29
flux Avatar answered Sep 21 '22 14:09

flux