You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何通过JSON配置覆盖Serilog代码中日志记录器的级别?

问题

原始问题

我编写了以下代码:

return Host.CreateDefaultBuilder()
           .UseSerilog((context, services, configuration) => configuration
               .MinimumLevel.Verbose()
               .ReadFrom.Configuration(_configuration)
               .ReadFrom.Services(services)
               .Enrich.FromLogContext()
               .Enrich.With(UserLoginEnricher.GetInstance()) 
               .Enrich.With(new LoggersAdditionalEnricher())
//CSV logger
               .WriteTo.Logger(x =>
               {
                   x.WriteTo.File(ApplicationConfiguration.FullPathToCsvFile,
                       rollingInterval: RollingInterval.Day, 
                       encoding: Encoding.Unicode, 
                       retainedFileCountLimit: ApplicationConfiguration.AppSettingsOptions.RetainDataCount, 
                       outputTemplate: "{Message}{NewLine}");

                   //log filter
                   x.Filter.ByIncludingOnly(e =>
                   {
                       if (!e.Properties.ContainsKey(nameof(LogType)))
                           return false;
                       return e.Properties[nameof(LogType)].ToString() == LogType.CSV.ToString();
                   });
               })
               .WriteTo(x =>{...})
               .WriteTo(x =>{...});

是否可以通过Serilog的JSON配置修改File日志记录器的最低级别,且无需修改代码?

我的Serilog JSON配置如下:

"Serilog": {
    "Using": [
      "Serilog.Sinks.File"
    ],
    "MinimumLevel": {
      "Default": "Verbose",
      "Override": {
        "Microsoft": "Warning",
        "Microsoft.EntityFrameworkCore.Database.Command": "Warning"
        }
    }
  }

需求是:多个日志记录器中,所有日志记录器以Warning级别写入,仅CSV日志记录器以Information级别写入。


更新补充

我在代码中写了多个写入文件的WriteTo日志记录器,希望不修改代码的前提下,让其中一个(CSV那个)用Information级别,其他用Warning级别。

我猜测因为文件名是动态生成的(示例:[_RU-PF10PUV1_][_Vlad.Pupkin_][_CalendarCollector_OutlookCalendarLog_][_20220921.csv),所以没法通过JSON配置重写这些日志记录器,这个猜测对吗?

另外我想知道能不能通过JSON配置覆盖现有代码配置,比如:

"Override": 
{
"Utility.Logging.LogType.CSV": "Information"// LogType.CSV是日志消息的属性
}

有没有解决办法?


解答

1. 关于动态文件名的猜测正确

Serilog的JSON配置只能通过固定标识(如sink类型、命名空间)或预设过滤规则匹配日志记录器,你的文件名是动态生成的,JSON无法识别这种动态路径的sink,确实没法直接定位到CSV日志记录器单独修改级别。

2. 针对日志属性的Override配置无效

你尝试的"Utility.Logging.LogType.CSV": "Information"不生效,因为Serilog的MinimumLevel.Override仅支持按命名空间/类型名称设置级别,不支持直接通过日志属性过滤配置。

3. 无需改代码的可行方案

方案一:用过滤器扩展实现级别区分

需要引入Serilog.Filters.Expressions包,然后修改JSON配置:

"Serilog": {
    "Using": [
      "Serilog.Sinks.File",
      "Serilog.Filters.Expressions"
    ],
    "MinimumLevel": {
      "Default": "Warning",
      "Override": {
        "Microsoft": "Warning",
        "Microsoft.EntityFrameworkCore.Database.Command": "Warning"
      }
    },
    "Filter": [
      {
        "Name": "ByIncludingOnly",
        "Args": {
          "expression": "LogType = 'CSV'"
        }
      },
      {
        "Name": "WithMinimumLevel",
        "Args": {
          "level": "Information"
        }
      }
    ]
  }

配置逻辑:全局默认Warning级别,所有LogType为CSV的日志会被过滤器单独提升到Information级别,刚好匹配你代码中CSV日志器的过滤规则,实现CSV日志器记录Information级内容,其他日志器仅记录Warning及以上。

方案二:极小代码改动+JSON配置(可选)

如果可以接受一行代码修改,可在CSV日志器的WriteTo.File中增加读取配置的参数:

x.WriteTo.File(
    ApplicationConfiguration.FullPathToCsvFile,
    rollingInterval: RollingInterval.Day,
    encoding: Encoding.Unicode,
    retainedFileCountLimit: ApplicationConfiguration.AppSettingsOptions.RetainDataCount,
    outputTemplate: "{Message}{NewLine}",
    restrictedToMinimumLevel: _configuration.GetValue<LogEventLevel>("Serilog:Sinks:CSV:MinimumLevel", LogEventLevel.Information)
);

然后在JSON中新增配置节点:

"Serilog": {
    // 原有配置...
    "Sinks": {
      "CSV": {
        "MinimumLevel": "Information"
      }
    }
  }

后续可直接通过JSON调整级别,无需再改代码。

总结

完全不想改代码的话,优先选方案一;能接受极小代码改动的话,方案二更直接。

内容的提问来源于stack exchange,提问作者Владимир

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.18 13:15:41