JianYA
JianYA

Reputation: 3024

.NET Core Serilog Add username to logs via enrichment or middleware

I am trying to add username to my logs. The documentation shows this:

class ThreadIdEnricher : ILogEventEnricher
{
    public void Enrich(LogEvent logEvent, ILogEventPropertyFactory propertyFactory)
    {
        logEvent.AddPropertyIfAbsent(propertyFactory.CreateProperty(
                "ThreadId", Thread.CurrentThread.ManagedThreadId));
    }
}

However, I've read somewhere else that I need to use middleware to add the usernames to the logs.

This is what I have so far:

Middleware to get the current users username

public class UserNameEnricher 
{
    private readonly RequestDelegate next;

    public UserNameEnricher(RequestDelegate next)
    {
        this.next = next;
    }

    public Task Invoke(HttpContext context)
    {
        LogContext.PushProperty("UserName", context.User.Identity.Name);

        return next(context);
    }
}

Startup.cs

app.UseAuthentication();
app.UseMiddleware<UserNameEnricher>();

Program.cs

Log.Logger = new LoggerConfiguration()
   .ReadFrom.Configuration(Configuration)
   .Filter.ByExcluding(Matching.FromSource("Microsoft"))
   .Filter.ByExcluding(Matching.FromSource("System"))
   .Enrich.FromLogContext()
   .CreateLogger();

However despite all these configurations, the usernames still aren't appearing. What am I missing?

Serilog Configuration:

"Serilog": {
    "MinimumLevel": "Information",
    "Override": {
      "Microsoft": "Critical",
    },
    "WriteTo": [
      {
        "Name": "MSSqlServer",
        "Args": {
          "connectionString": "Server=.\\SQLEXPRESS;Database=App-7661DEE4-C53F-4E49-B140-2AFAA2C85927;Integrated Security=True;Trusted_Connection=True;MultipleActiveResultSets=true;",
          "schemaName": "App",
          "tableName": "EventLogs"
        }
      }
    ]
  },

Upvotes: 2

Views: 6123

Answers (1)

Edward
Edward

Reputation: 29976

For making it work, you need to specify outputTemplate.

Properties from events, including those attached using enrichers, can also appear in the output template.

Output templates

Here is a demo code which is used for RollingFile.

var output = "{Timestamp:yyyy-MM-dd HH:mm:ss.fff zzz} [{Level}] {Message} {ActionName} {UserName} {NewLine}{Exception}";

        Log.Logger = new LoggerConfiguration()
               .Enrich.FromLogContext() // Populates a 'User' property on every log entry
               .WriteTo.RollingFile("Logs/app-{Date}.txt",outputTemplate: output)
               .CreateLogger();

Note

{UserName} in output should map UserName in LogContext.PushProperty("UserName", context.User.Identity.Name);.

Update:

configure by appsetting.json

  "Serilog": {
"MinimumLevel": "Information",
"Override": {
  "Microsoft": "Critical"
},
"WriteTo": [
  {
    "Name": "RollingFile",
    "Args": {
      "pathFormat": "Logs/app-{Date}.txt",
      "outputTemplate": "{Timestamp:yyyy-MM-dd HH:mm:ss.fff zzz} [{Level}] {Message} {UserName} {ActionName}  {NewLine} {Exception}"
    }
  }
]
   }

Upvotes: 3

Related Questions