My Serilog configuration code looks like this:
Log.Logger = new LoggerConfiguration()
.Enrich.WithExceptionDetails()
.Enrich.FromLogContext()
.MinimumLevel.Warning()
// .MinimumLevel.Override("Microsoft", LogEventLevel.Verbose)
// .MinimumLevel.Override("System", LogEventLevel.Verbose)
// .MinimumLevel.Override("Microsoft.AspNetCore.Authentication", LogEventLevel.Verbose)
.WriteTo.Console( outputTemplate: "[{Timestamp:HH:mm:ss} {Level}] {SourceContext}{NewLine}{Message:lj}{NewLine}{Exception}{NewLine}", theme: AnsiConsoleTheme.Literate )
// .WriteTo.File()
.CreateLogger();
I'd like to change this configuration at runtime, unfortunately because Serilog uses a "fluent" style of API it makes it somewhat messy. For example, if I want to enable or disable console and file logging at runtime:
Boolean enableConsoleLogging = ...
Boolean enableFileLogging = ...
LoggerConfiguration builder = new LoggerConfiguration()
.Enrich.WithExceptionDetails()
.Enrich.FromLogContext()
.MinimumLevel.Warning();
if( enableConsoleLogging )
{
builder = builder
.WriteTo.Console( outputTemplate: "[{Timestamp:HH:mm:ss} {Level}] {SourceContext}{NewLine}{Message:lj}{NewLine}{Exception}{NewLine}", theme: AnsiConsoleTheme.Literate )
}
if( enableFileLogging )
{
builder = builder
.WriteTo.File( ... )
}
Log.Logger = builder.CreateLogger();
...which is not exactly elegant.
I know I could add my own If
extension method (but I'm not keen on extending an existing API design like that, even if it does look prettier):
Log.Logger = new LoggerConfiguration()
.Enrich.WithExceptionDetails()
.Enrich.FromLogContext()
.MinimumLevel.Warning()
.If( enableConsoleLogging, b => b.WriteTo.Console( outputTemplate: "[{Timestamp:HH:mm:ss} {Level}] {SourceContext}{NewLine}{Message:lj}{NewLine}{Exception}{NewLine}", theme: AnsiConsoleTheme.Literate ) )
.If( enableFileLogging, b => b.WriteTo.File( ... ) )
.CreateLogger();
public static LoggerConfiguration If( this LoggerConfiguration cfg, Boolean test, Func<LoggerConfiguration,LoggerConfiguration> action )
{
if( test ) return action( cfg );
else return cfg;
}
What alternatives exist to toggle different Serilog options at runtime? Are there any approaches that can be used with other "Fluent" APIs?