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?
Serilog is a . NET library that provides diagnostic logging to files, the console, and almost everywhere you would like. Serilog can be used in classic . NET Framework applications and for applications running on the latest and greatest .
From the official site:https://serilog.net/, "Serilog provides diagnostic logging to files, the console, and elsewhere. It is easy to set up, has a clean API, and is portable between recent . NET platforms. Unlike other logging libraries, Serilog is built with powerful structured event data in mind."
Serilog defines several levels of log events. From low to high, these are Verbose , Debug , Information , Warning , Error and Fatal . You can set the minimum level you want to log, meaning that events for that level or higher will be logged.
Serilog 2.9.0 introduces conditional sinks. Using .WriteTo.Conditional
you specify the condition that defines if the sink will be written to or not.
e.g.
bool enableConsoleLogging = ...
bool enableFileLogging = ...
var builder = new LoggerConfiguration()
.Enrich.WithExceptionDetails()
.Enrich.FromLogContext()
.MinimumLevel.Warning()
.WriteTo.Conditional(evt => enableConsoleLogging, wt => wt.Console())
.WriteTo.Conditional(evt => enableFileLogging, wt => wt.File(...));
Log.Logger = builder.CreateLogger();
// ...
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With