Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Alternative in Serilog for NLog's "final" rule

It's possible to configure NLog like this:

<rules>
 <logger name="Microsoft.EntityFrameworkCore.*" minlevel="Trace" writeTo="file-ef" final="true" />
 <logger name="Microsoft.*" minlevel="Trace" writeTo="file-http,console" final="true" />
 <logger name="*" minlevel="Trace" writeTo="file,console" />
</rules>

The final keyword for rules enables the possibility to use separate targets for:

  1. Microsoft.EntityFrameworkCore.* loggers
  2. Other Microsoft.* loggers
  3. All other loggers

The configuration is straightforward and logical, I can easily add another condition without modifying all other rules.

With Serilog to do the same thing I have to write the following code:

const string format = "[{Timestamp:HH:mm:ss.fff} {ThreadId} {Level:u3}] {Message:lj} [{SourceContext}] {NewLine}{Exception}";
Log.Logger = new LoggerConfiguration()
            .MinimumLevel.Verbose()
            .Enrich.FromLogContext()
            .Enrich.WithThreadId()
            .WriteTo.Console(outputTemplate: format)
            .WriteTo.Logger(cfg => cfg
                .Filter.ByIncludingOnly(Matching.FromSource("Microsoft.AspNetCore"))
                .WriteTo.RollingFile(@"logs\{Date}.http.log", outputTemplate: format, retainedFileCountLimit: null, buffered: true))
            .WriteTo.Logger(cfg => cfg
                .Filter.ByIncludingOnly(Matching.FromSource("Microsoft.EntityFrameworkCore"))
                .WriteTo.RollingFile(@"logs\{Date}.ef.log", outputTemplate: format, retainedFileCountLimit: null, buffered: true))
            .WriteTo.Logger(cfg => cfg.Filter
                .ByExcluding(Matching.FromSource("Microsoft"))
                .WriteTo.RollingFile(@"logs\{Date}.log", outputTemplate: format, retainedFileCountLimit: null, buffered: true))
            .CreateLogger();

To add another condition I would have to exclude it from all the other filters.

Question: am I missing something or there is no easy way to skip other rules if one is matched?

like image 400
Andrey Kamyshanov Avatar asked Nov 08 '22 13:11

Andrey Kamyshanov


1 Answers

This isn't a scenario where Serilog's API is particularly strong, but Serilog.Sinks.Map covers this case.

    // Install-Package Serilog.Sinks.Map -Pre

    var isAsp = Matching.FromSource("Microsoft.AspNetCore");
    var isEF = Matching.FromSource("Microsoft.EntityFrameworkCore");
    var isMS = Matching.FromSource("Microsoft");

    Log.Logger = new LoggerConfiguration()
        .WriteTo.Map(le => isAsp(le) ? ".http" :
                            isEF(le) ? ".ef" :
                            !isMS(le) ? ".other" :
                            "",
            (slug, wt) => wt.RollingFile($"logs\\{{Date}}{slug}.log"))
        .CreateLogger();
like image 101
Nicholas Blumhardt Avatar answered Nov 15 '22 06:11

Nicholas Blumhardt