Serilog 中不同级别的不同日志文件

Different log file for different levels in Serilog

我正在使用 serilog,我需要将不同的日志级别保存到不同的文件中(例如 debug-20200708.log 用于调试级别,info-20200798.log 用于调试级别和...)

我使用了下面的代码,但它不能正常工作。

var baseLogger = new Serilog.LoggerConfiguration()
    .WriteTo.Logger(l => l
        .Filter.ByIncludingOnly(e => e.Level == LogEventLevel.Fatal))
        .WriteTo.File(
            path: GetLogPath(LogEventLevel.Fatal),
            formatter: formatter)

    .WriteTo.Logger(l => l
        .Filter.ByIncludingOnly(e => e.Level == LogEventLevel.Error))
        .WriteTo.File(
            path: GetLogPath(LogEventLevel.Error),
            formatter: formatter)

    .WriteTo.Logger(l => l
        .Filter.ByIncludingOnly(e => e.Level == LogEventLevel.Warning))
        .WriteTo.File(
            path: GetLogPath(LogEventLevel.Warning),
            formatter: formatter)

    .WriteTo.Logger(l => l
        .Filter.ByIncludingOnly(e => e.Level == LogEventLevel.Information))
        .WriteTo.File(
            path: GetLogPath(LogEventLevel.Information),
            formatter: formatter)

    .WriteTo.Logger(l => l
        .Filter.ByIncludingOnly(e => e.Level == LogEventLevel.Debug))
        .WriteTo.File(
            path: GetLogPath(LogEventLevel.Debug),
            formatter: formatter)

    .WriteTo.Logger(l => l
        .Filter.ByIncludingOnly(e => e.Level == LogEventLevel.Verbose))
        .WriteTo.File(
            path: GetLogPath(LogEventLevel.Verbose),
            formatter: formatter)
    .Enrich.FromLogContext();

_logger = baseLogger.CreateLogger();

我在 SQLServer 中插入不同表时遇到了这个问题。我通过这样做解决了它

Log.Logger = new LoggerConfiguration()
.WriteTo.Conditional(x => x.Level == Serilog.Events.LogEventLevel.Error, conf => conf.MSSqlServer(Configuration.GetConnectionString("LogConnectionString"),
    new SinkOptions { AutoCreateSqlTable = true, TableName = "Error" }))
.WriteTo.Conditional(x => x.Level == Serilog.Events.LogEventLevel.Warning, conf => conf.MSSqlServer(Configuration.GetConnectionString("LogConnectionString"),
   new SinkOptions { AutoCreateSqlTable = true, TableName = "Warning" }))
.WriteTo.Conditional(x => x.Level == Serilog.Events.LogEventLevel.Debug, conf => conf.MSSqlServer(Configuration.GetConnectionString("LogConnectionString"),
    new SinkOptions { AutoCreateSqlTable = true, TableName = "Debug" }))
.WriteTo.Conditional(x => x.Level == Serilog.Events.LogEventLevel.Information, conf => conf.MSSqlServer(Configuration.GetConnectionString("LogConnectionString"),
    new SinkOptions { AutoCreateSqlTable = true, TableName = "Information" }))
.WriteTo.Conditional(x => x.Level == Serilog.Events.LogEventLevel.Verbose, conf => conf.MSSqlServer(Configuration.GetConnectionString("LogConnectionString"),
   new SinkOptions { AutoCreateSqlTable = true, TableName = "Verbose" }))
.CreateLogger();

它不起作用的主要原因是因为您没有使用过滤器的 .WriteTo,而是使用主管道的 .WriteTo(它不没有应用过滤器)。

例如而不是:

.WriteTo.Logger(l => l
    .Filter.ByIncludingOnly(e => e.Level == LogEventLevel.Fatal))
.WriteTo.File(
    path: GetLogPath(LogEventLevel.Fatal),
    formatter: formatter)

您需要(注意括号中的区别):

.WriteTo.Logger(l => l
    .Filter.ByIncludingOnly(e => e.Level == LogEventLevel.Fatal)
    .WriteTo.File(
        path: GetLogPath(LogEventLevel.Fatal),
        formatter: formatter))

这适用于您的每个 .WriteTo 电话,因为它们都有相同的问题。

修复该问题后,您会看到日志现在已写入相应文件,VerboseDebug 除外(文件为空)。这样做的原因是因为 Serilog 的默认 MinimumLevelInformation 所以任何低于它的都会被忽略。要解决此问题,您需要在日志记录管道配置中将 MinimumLevel 设置为 Verbose

var baseLogger = new Serilog.LoggerConfiguration()
    .MinimumLevel.Verbose()
    .WriteTo.Logger(l => l
    // ...

ps:还有一种不同的方法可以使用 Serilog.Sinks.Map sink which you can see an example here.

来完成您正在做的事情