.net-coreserilog

How to force log output regardless of filter level for startup and shutdown events


I'm looking for the easiest / most elegant way to force log output for startup and shutdown events, regardless of the current output log level. This is so that logging to file will always have startup and shutdown events even if no warning or error events were logged.

I did find a similar question on github dating to 2019 using ForContext, I am wondering if there is currently an easier way?


Solution

  • The example you linked to is actually very simple and easy, so it's not clear why it wouldn't work for your basic ask.

    In this comment, it sounds like you want to do an override only for a single sink. That is more complicated, and will require you to use a sub-logger. And due to how sub-loggers work, you will need to write a custom filter instead of using an Override. Still, once you've got the configuration figured out, the pattern for logging is pretty straightforward.

    var loggerConfig = new LoggerConfiguration()
            .MinimumLevel.Debug()
            .WriteTo.Logger(lc =>
                lc
                .MinimumLevel.Debug()
                .Filter.ByIncludingOnly(logEvent =>
                    (logEvent.Properties.TryGetValue("IsLifecycleEvent", out var val) && val is ScalarValue { Value: true }) ||
                    logEvent.Level >= LogEventLevel.Warning)
                .WriteTo.Console( // This could be a file logger instead
                    outputTemplate: "{Level:u3} (File): {Message:lj}{NewLine}"
                )
            )
            .WriteTo.Logger(lc =>
                lc
                .MinimumLevel.Information()
                .WriteTo.Console(
                    outputTemplate: "{Level:u3} (Console): {Message:lj}{NewLine}"
                ))
            ;
    Serilog.ILogger logger = loggerConfig.CreateLogger();
    Serilog.Log.Logger = logger;
    
    Log.ForContext("IsLifecycleEvent", true).Debug("Starting Up");
    Log.Debug("Debug");
    Log.Information("Information");
    Log.Warning("Warning");
    Log.ForContext("IsLifecycleEvent", true).Debug("Shutting Down");
    

    In the above example, the log messages come out like this:

    Combined:

    DBG (File): Starting Up
    INF (Console): Information
    WRN (File): Warning
    WRN (Console): Warning
    DBG (File): Shutting Down
    

    File:

    DBG (File): Starting Up
    WRN (File): Warning
    DBG (File): Shutting Down
    

    Console:

    INF (Console): Information
    WRN (Console): Warning
    

    As you can see, the File sink only sees things at Warning level and higher, unless they are tagged as being lifecycle-related. The Console sink receives everything at Information level and higher.