Serilog: Multi-file output using subloggers and filters

771 views Asked by At

My C# Serilog output should go to two different files: a "regular" output when using 1 set of expressions (WriteOperationalLog), and a JSON output when using another (WriteJsonLog).

As far as I understand it, I think I should be using subloggers to filter out the JSON expression and send it to my seperate file output. Whenever I try to use the Filters though, it leads to infinite loops.

My logger creation function looks as follows:

Log.Logger = new LoggerConfiguration()
.MinimumLevel.Debug()
.WriteTo.File(filepath, rollingInterval: RollingInterval.Day) 
.WriteTo.Logger(lc => lc
    .Filter.ByIncludingOnly(WriteJsonLog)
    .WriteTo.File(new ExpressionTemplate("{ @m } \n"), filepathJson, rollingInterval: RollingInterval.Day))
.CreateLogger();

If anyone can point me to documentation on how to use the .Filter function, that'd be very helpful, as I haven't been able to find anything good myself.

EDIT: I managed to figure it out!

My logger configuration now looks as follows:

We now use Serilog.Context to add a "JSON" property in the WriteJSONLog function:

using(LogContext.PushProperty("JSON", true))
{
    Log.Information(json);
}

With the Serilog.Filters package we can then test whether the logEvent contains that JSON property. My LoggerConfiguration also had a few other errors, but now it looks like this:

Log.Logger = new LoggerConfiguration()
.Enrich.FromLogContext() //enable the loggers to add properties to our messages (to add the JSON property)
.MinimumLevel.Debug()
.WriteTo.Logger(lc => lc
    .Filter.ByExcluding(Matching.WithProperty("JSON")) // Write the messages that DO NOT have the JSON property to the regular file
    .WriteTo.File(filepath, rollingInterval: RollingInterval.Day)) 
.WriteTo.Logger(lc => lc
    .Filter.ByIncludingOnly(Matching.WithProperty("JSON")) // Write all messages that DO have the JSON property to our JSON output
    .WriteTo.File(new ExpressionTemplate("{ @m } \n"), filepathJson, rollingInterval: RollingInterval.Day)) //message formatting to only output the string, no extras
.CreateLogger();
0

There are 0 answers