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

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

问题描述:

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

I am using serilog and I need to save different log levels to different files ( for example debug-20200708.log for debug level, info-20200798.log for debug level and ...)

我使用了以下代码,但无法正常工作.

I used below code but it does not work correctly.

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();

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

The main reason it doesn't work is because you're not using the .WriteTo of the filter, and instead you're using the .WriteTo of the main pipeline (which doesn't have filters applied).

例如代替:

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

您需要(请注意括号中的内容):

You need (notice the difference in parentheses):

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

这适用于您遇到的每个 .WriteTo 调用,因为它们都存在相同的问题.

This applies for each of the .WriteTo calls you have as they all have the same issue.

修复此问题后,您会看到日志现在已写入相应的文件,除了 Verbose Debug (文件为空)之外.这样做的原因是因为Serilog的默认 MinimumLevel Information ,因此任何低于此值的内容都会被忽略.要解决此问题,需要在日志记录管道配置中将 MinimumLevel 设置为 Verbose :

Once you fix that, you'll see that the logs are written to the corresponding files now, except for Verbose and Debug (files are empty). The reason for that is because Serilog's default MinimumLevel is Information so anything lower than that is ignored. To resolve that you need to set the MinimumLevel to Verbose in the logging pipeline configuration:

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


ps:还有一种使用 Serilog.Sinks做事的方法..map 水槽,您可以在此处查看示例.


ps: There's also a different approach to doing what you're doing using the Serilog.Sinks.Map sink which you can see an example here.