Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Serilog PushProperty in appsettings-configuration not working

ASP.NET Core 2.2.0 | Serilog.AspNetCore 2.1.1 | Serilog.Sinks.File 4.0.0

I'm initializing Serilog in Program.cs, reading the configuration from appsettings.json and adding middleware in Startup.cs -> Configure. Some snippets:

Program.cs

public static void Main(string[] args)
{
    Log.Logger = new LoggerConfiguration()
        .ReadFrom.Configuration(Configuration)
        .CreateLogger();

    try
    {
        Log.Information("Starting web host");
        CreateWebHostBuilder(args).Build().Run();
    }
    catch (Exception ex)
    {
        Log.Fatal(ex, "Host terminated unexpectedly");
    }
    finally
    {
        Log.CloseAndFlush();
    }
}

public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
        WebHost.CreateDefaultBuilder(args)
            .UseStartup<Startup>()
            .UseConfiguration(Configuration)
            .UseSerilog();

Startup.cs

public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
    if (env.IsDevelopment() || env.IsStaging())
    {
        app.UseDeveloperExceptionPage();
    }
    else
    {
        app.UseExceptionHandler("/Error");
        app.UseHsts();
        app.UseRewriter(new RewriteOptions()
            .AddRedirectToWww()
            .AddRedirectToHttps());
    }
    app.UseSession();
    app.UseAuthentication();
    app.UseMiddleware<SerilogAddUserInfo>();

    app.UseStaticFiles();

    app.UseCookiePolicy();
    app.UseMvc();
}

appsettings.json

"Serilog": {
  "MinimumLevel": {
    "Default": "Debug",
    "Override": {
      "Microsoft": "Information",
      "System": "Warning"
    }
  },
  "Enrich": "FromLogContext",
  "WriteTo": [
    {
      "Name": "File",
      "Args": {
        "path": "logs/log.txt",
        "rollingInterval": "Hour",
        "outputTemplate": "{Timestamp:o} [{Level:u3}] [IP {Address}] [Session {Session}] [{SourceContext}] {Site}: {Message}{NewLine}"
      }
    }
  ]
}

SerilogMiddleware.cs

public class SerilogAddUserInfo
{
    private readonly RequestDelegate _next;

    public SerilogAddUserInfo(RequestDelegate next)
    {
        _next = next;
    }

    public async Task Invoke(HttpContext context)
    {
        using (LogContext.PushProperty("Address", context.Connection.RemoteIpAddress))
        using (LogContext.PushProperty("Session", context.Session.GetString("SessionGUID") ?? "Unknown"))
        {
            await _next.Invoke(context);
        }
    }
}

In the middleware I want to push some properties (Address, Session and more) to the logs. When I configure Serilog as written above the properties are not visible in the logs. When I configure Serilog using the next snippet in Program.cs, it actually works:

Log.Logger = new LoggerConfiguration()
    .MinimumLevel.Debug()
    .MinimumLevel.Override("Microsoft", LogEventLevel.Information)
    .MinimumLevel.Override("System", LogEventLevel.Information)
    .Enrich.FromLogContext()
    .WriteTo.File("logs/log.txt", rollingInterval: RollingInterval.Hour,outputTemplate: "{Timestamp:o} [{Level:u3}] [IP {Address}] [Session {Session}] [{SourceContext}] {Site}: {Message}{NewLine}")
    .CreateLogger();

Why is there a difference? Or how can I use the PushProperty possibilities on an via-appsettings-configured-serilog?

like image 426
CribAd Avatar asked Mar 13 '19 12:03

CribAd


People also ask

What is LogContext PushProperty?

The LogContextPushing property onto the context will override any existing properties with the same name, until the object returned from PushProperty() is disposed, as the property A in the example demonstrates. Important: properties must be popped from the context in the precise order in which they were added.

What is Serilog Enricher?

Log Context enricher - Built in to Serilog, this enricher ensures any properties added to the Log Context are pushed into log events. Environment enrichers - Enrich logs with the machine or current user name.


1 Answers

You need to add only .Enrich.FromLogContext() when initializing Serilog in Program.cs

Log.Logger = new LoggerConfiguration()
        .ReadFrom.Configuration(configuration)
        .Enrich.FromLogContext()
        .CreateLogger();

Check Inline initialization in Serilog.AspNetCore documentation.

like image 68
ElasticCode Avatar answered Oct 21 '22 10:10

ElasticCode