12

In a long running process (such as a Windows service or an ASP.NET application) it’s sometimes desirable to temporarily increase the log level without stopping the application. NLog can monitor logging configuration files and re-read them each time they are modified.

https://github.com/nlog/NLog/wiki/Configuration-file#automatic-reconfiguration

Is this also possible with Serilog?

MarredCheese
  • 17,541
  • 8
  • 92
  • 91
Robin van der Knaap
  • 4,060
  • 2
  • 33
  • 48
  • 1
    Nowadays you can also use dynamic levels: https://github.com/serilog/serilog/wiki/Writing-Log-Events#dynamic-levels – Michiel Dec 23 '14 at 21:14
  • Nice suggestion, seems like a simple solution. I'm not currently working anymore with serilog, but will give it try when I do. – Robin van der Knaap Dec 23 '14 at 21:26

1 Answers1

19

Use LoggingLevelSwitch for this:

// Set initial level
var levelSwitch = new LoggingLevelSwitch(LogEventLevel.Warning);

Log.Logger = new LoggerConfiguration()
  .MinimumLevel.ControlledBy(levelSwitch)
  .WriteTo.Console()
  .CreateLogger();

Log.Debug("This is not shown");

levelSwitch.MinimumLevel = LogEventLevel.Debug;

Log.Debug("This will now be shown, since the level has changed");

When the `levelSwitch.MinimumLevel is changed, the logger will pick up the new minimum level setting.

For Serilog 1.4.10 and earlier

Serilog doesn't bake this in as a first-class notion.

This can be emulated using a filter:

// Stored e.g. in a static field
volatile LogEventLevel minLevel;

Log.Logger = new LoggerConfiguration()
    .Filter.ByExcluding(evt => (int)evt.Level < (int)minLevel)
    .CreateLogger();

It'd be up to you to determine how minLevel gets modified as the app runs.

This approach isn't as efficient as setting the minimum level natively since the events will be generated in all cases, but the actual overhead shouldn't be huge.

Depending on the sinks you're using, an alternative is to simply create multiple loggers, and choose between them:

var minVerboseLogger = new LoggerConfiguration()
    .MinimumLevel.Verbose()
    .CreateLogger();

var minWarningLogger = new LoggerConfiguration()
    .MinimumLevel.Warning()
    .CreateLogger();

// Somewhere else:
public ILogger Log
{
    get { return isVerbose ? minVerboseLogger : minWarningLogger; }
}

The second approach is preferable, but won't behave nicely if the two loggers need to share the same log file. If you need to write to a file in both cases, chain the higher-level logger to the lower one, e.g.:

var minWarningLogger = new LoggerConfiguration()
    .MinimumLevel.Warning()
    .WriteTo.Sink((ILogEventSink)minVerboseLogger)
    .CreateLogger();

Admittedly this is more complex than the NLog approach you linked; I'll give some thought as to how we might make it smoother.

Nicholas Blumhardt
  • 30,271
  • 4
  • 90
  • 101