Search code examples
c#asp.net-core.net-coreserilog

Add Username via LogContext in Serilog


I am using Serilog for logging in .NET Core 6.0 Web API application. I want to add logged user name to logs. My middleware is

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);
    }
}

and in Program.cs

var _logger = new LoggerConfiguration()
 .ReadFrom.Configuration(builder.Configuration)    
 .MinimumLevel.Override("Microsoft.AspNetCore", LogEventLevel.Warning)
 .Enrich.FromLogContext()
 .CreateLogger();

Log.Logger = _logger; //new 
builder.Logging.ClearProviders();
builder.Logging.AddSerilog(_logger);

and in appsettings

 "Serilog": {
"MinimumLevel": {
  "Default": "Information",
  "Override": {
    "Microsoft": "Warning",
    "Microsoft.Hosting.Lifetime": "Information"
  }
},
"WriteTo": [
  {
    "Name": "File",
    "Args": {
      "path": "C:\\Debug\\webapi-.log",
      "rollingInterval": "Day",
      "outputTemplate": "[{Timestamp:yyyy-MM-dd HH:mm:ss} {CorrelationId} {Level:u3}] {Username} {Message:lj}{NewLine}{Exception}"
    }
  }
]

But User name is not writing in logs. I can see user name in middleware but not in logs. What am I missing here?


Solution

  • Property names a case-sensitive, you are pushing UserName but template has {Username}. Consolidate names, also you might want to wrap the PushProperty in using:

    public async Task Invoke(HttpContext context)
    {
        using (LogContext.PushProperty("Username", context.User.Identity.Name))
        {
            await next(context);
        }
    }