I'm going to implement Serilog within .net standard 2.0 library. I'm looking for a way to choose which sink(s) should be used for each log line.
Lets say that we define 2 sinks within the configuration (console & file) :
Log.Logger = new LoggerConfiguration()
.MinimumLevel.Debug()
.WriteTo.Console()
.WriteTo.File("c:\\temp\\SerilogTets.txt")
.CreateLogger();
After this, we are going to write one log rule :
Log.Information("Hello, world!"); //<- how can we define which sink we want to use
I'm looking for a way howto define for which sink(s) those lines should be logged for :
Without relying on what loglevel it is.
Thank you in advance!
Kind regards, Kurt
In Serilog you can do this separation via sub-loggers using filters or via Serilog.Sinks.Map, using context properties to decide which logger will include or exclude certain messages.
The example below defines that all log events will be written to both the Console and to a File, by default, however if the log event has a property called FileOnly
in the log context, it will not be written to the Console, and likewise if the log event has a property called ConsoleOnly
, it will not be written to the File.
using Serilog;
using Serilog.Context;
using Serilog.Filters;
// ...
Log.Logger = new LoggerConfiguration()
.MinimumLevel.Verbose()
.Enrich.FromLogContext()
.WriteTo.Logger(c =>
c.Filter.ByExcluding(Matching.WithProperty("FileOnly"))
.WriteTo.Console())
.WriteTo.Logger(c =>
c.Filter.ByExcluding(Matching.WithProperty("ConsoleOnly"))
.WriteTo.File("C:\\Temp\\SerilogTests.txt"))
.CreateLogger();
// Writes to both Console & File
Log.Information("Hello, world! (Console and File)");
using (LogContext.PushProperty("ConsoleOnly", value: true))
{
// Writes only to the Console
Log.Information("Hello, world! (Console)");
}
using (LogContext.PushProperty("FileOnly", value: true))
{
// Writes only to the File
Log.Information("Hello, world! (File Only)");
}
Log.CloseAndFlush();
N.B.: Ideally you'll come up with better property names that are more generic, so that when you are writing logs within your application it doesn't have to know anything about "Console" or "File". e.g. You could have a property called Secret
or Classified
and decide where to write the logs based on the presence of this property or not.
There are different ways to add properties to a log event, including adding the property in the message template directly when you Log.Information
, etc., via LogContext.PushProperty
as in the example above, and vi Log.ForContext
.
You can see other examples of filtering, sub-loggers, and Serilog.Sinks.Map here: