C# - Serilog, how to change the log level dynamically at runtime

The secret to changing the log level at runtime in your application is the LoggingLevelSwitch. This can be applied in two places, one is the MinimumLevel on the loggerConfiguration:

var levelSwitch = new LoggingLevelSwitch();
levelSwitch.MinimumLevel = LogEventLevel.Warning;

Log.Logger = loggerConfiguration
    .MinimumLevel.ControlledBy(levelSwitch) //here!
    .WriteTo
    .Console()
    .CreateLogger();

The other is on a specific sink, for example a console sink:

var levelSwitch = new LoggingLevelSwitch();
levelSwitch.MinimumLevel = LogEventLevel.Warning;

Log.Logger = loggerConfiguration
    .WriteTo
    .Console(levelSwitch: levelSwitch) //here!
    .CreateLogger();

If you set both the default levelswitch on the configuration and on a sink, the highest level is applied (as far as I can deduce). Meaning, if the default in the configuration is set to Warning and the sink to Information, Warning will be the level applied. If you wish to set the log level differently for your sinks, the default log level should be the same as the lowest sink level. Remember, you can use the same LoggingLevelSwitch for several sinks and the default configuration!

In order to change the log level, you simply assign a new log level to the LoggingLevelSwitch:

levelSwitch.MinimumLevel = LogEventLevel.Warning;

That is all there is to it.

With dependency injection

If you want to to change the level in a controller or some other place, you can use your level switch as a dependency, by adding it to the IoC container:

var levelSwitch = new LoggingLevelSwitch();
levelSwitch.MinimumLevel = LogEventLevel.Warning;
builder.Services.AddSingleton<LoggingLevelSwitch>(levelSwitch);

You can the resolve and change this through app.Services:

using (var scope = app.Services.CreateScope())
{
    var logLevelSwitch = scope.ServiceProvider.GetRequiredService<LoggingLevelSwitch>();
    logLevelSwitch.MinimumLevel = LogEventLevel.Information;
}

or constructor injection through a controller:

public class LogLevelController : Controller
{
    private readonly LoggingLevelSwitch loggingLevelSwitch;

    public LogLevelController(LoggingLevelSwitch loggingLevelSwitch)
    {
        this.loggingLevelSwitch = loggingLevelSwitch;
    }

    public async Task ChangeLogLevel()
    {
        loggingLevelSwitch.MinimumLevel = LogEventLevel.Information;
    }
}

Now.. do not let everyone out there change your log levels, the above are just examples :)

That is all

I hope you found the above useful! I think the biggest pitfall is when you try to have multiple switches, so try to keep things simple. Let me know in the comments if the above was helpful!

Have a great day!