如何针对不同的接收器以不同的方式覆盖 Serilog 级别?

pio*_*ojo 6 c# serilog

我的场景是:文件接收器应该包含所有内容。另一个接收器应包含信息消息,但需要注意的是 Microsoft.* 消息很烦人,因此这些消息应仅限于警告。两个sink如何单独配置?我尝试的第一件事是:

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");
Run Code Online (Sandbox Code Playgroud)

在这种情况下,两个日志文件都是选择性的,并且“all.log”不包含所有日志消息。接下来,我尝试使用子记录器来完成此任务:

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();
Run Code Online (Sandbox Code Playgroud)

此配置效果更好,但较小的日志文件仍然包含本应被该.MinimumLevel.Override()选项阻止的行:

[INF] Microsoft.AspNet.Example: example log; should not go in the minimal file
Run Code Online (Sandbox Code Playgroud)

使用过滤器实际上是可行的,但我更喜欢简单的语法,这样更容易配置。

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();
Run Code Online (Sandbox Code Playgroud)

这是一个错误吗?为什么过滤器有效但设置最低级别却不起作用?

Cai*_*ete 3

不幸的是,MinimumLevel.Override()子记录器根本不支持。请参阅以下问题的更多内容:

Bug:MinimumLevel 覆盖忽略SourceContextLogEvent #1382

.Filter.ByExcluding就目前而言,这是一个很好的解决方法。