简体   繁体   中英

How can I override Serilog levels differently for different sinks?

My scenario is: a file sink should contain everything. Another sink should contain Information messages, with the caveat that Microsoft.* messages are annoying so those should be limited to Warning only. How can the two sinks be configured separately? The first thing I tried was:

string outputTemplate = "[{Level:u3}] {SourceContext}: {Message:lj}{NewLine}";

Log.Logger = new LoggerConfiguration()
    .MinimumLevel.Verbose()
    .WriteTo.File("Logs/all.log", outputTemplate: outputTemplate)

    .MinimumLevel.Information()
    .MinimumLevel.Override("Microsoft", Serilog.Events.LogEventLevel.Warning)
    .WriteTo.File("Logs/some.log", outputTemplate: outputTemplate)
    .CreateLogger();

var msLogger = Log.Logger.ForContext(Constants.SourceContextPropertyName, "Microsoft.AspNet.Example");
var logger = Log.Logger.ForContext(Constants.SourceContextPropertyName, "MyClass");

msLogger.Verbose("example log; should not go in the minimal file");
msLogger.Information("example log; should not go in the minimal file");
msLogger.Warning("example log");
logger.Verbose("example log; should not go in the minimal file");
logger.Information("example log");

In this case, both log files are selective and "all.log" does not contain all log messages. Next, I tried to accomplish this with sub-loggers:

Log.Logger = new LoggerConfiguration()
    .MinimumLevel.Verbose()
    .WriteTo.File("Logs/all.log", outputTemplate: outputTemplate)

    .WriteTo.Logger(lc => lc
        .MinimumLevel.Information()
        .MinimumLevel.Override("Microsoft", Serilog.Events.LogEventLevel.Warning)
        .WriteTo.File("Logs/some.log", outputTemplate: outputTemplate))
        .CreateLogger();

This config works better, but the smaller log file still contains this line which should have been blocked by the .MinimumLevel.Override() option:

[INF] Microsoft.AspNet.Example: example log; should not go in the minimal file

Using a filter actually works, but I prefer the simple syntax so it's easier to configure.

Log.Logger = new LoggerConfiguration()
    .MinimumLevel.Verbose()
    .WriteTo.File("Logs/all.log", outputTemplate: outputTemplate)

    .WriteTo.Logger(lc => lc
        .MinimumLevel.Information()
        .Filter.ByExcluding(logEvent =>
            logEvent.Level < LogEventLevel.Warning &&
            Matching.FromSource("Microsoft").Invoke(logEvent))
        .WriteTo.File("Logs/some.log", outputTemplate: outputTemplate))
        .CreateLogger();

Is this a bug? Why do filters work but setting the minimum level doesn't?

Unfortunately, MinimumLevel.Override() is not supported at all by sub-loggers. See more in the issue below:

Bug: MinimumLevel override ignores SourceContext of LogEvent #1382

.Filter.ByExcluding is a good workaround, for now.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM