如何基于Serilog全局最低级别控制日志写入,避免生成Debug文件?
直接用纯JSON配置没法实现“根据全局动态级别条件启用/禁用接收器”的逻辑,因为JSON是静态配置。不过可以通过代码结合JSON配置的方式完美满足你的需求,这里提供两种常用方案:
方案一:动态添加Debug接收器
在代码里根据LoggingLevelSwitch的当前级别,决定是否初始化Debug文件接收器。当全局级别设为Information及以上时,Debug接收器不会被创建,自然不会生成文件,也不会写入任何内容。
代码示例
// 初始化级别开关,后续可通过业务逻辑动态调整级别 var levelSwitch = new LoggingLevelSwitch(LogEventLevel.Information); // 读取JSON配置(JSON里只保留EventsLog的接收器配置) var config = new ConfigurationBuilder() .AddJsonFile("appsettings.json") .Build(); var loggerConfig = new LoggerConfiguration() .ReadFrom.Configuration(config) .MinimumLevel.ControlledBy(levelSwitch); // 仅当全局级别允许Debug日志时,才添加Debug文件接收器 if (levelSwitch.MinimumLevel <= LogEventLevel.Debug) { loggerConfig.WriteTo.File( path: "Logs/DebugLog.txt", rollingInterval: RollingInterval.Day, retainedFileCountLimit: 2, buffered: false, outputTemplate: "{Timestamp:yyyy-MM-dd HH:mm:ss.fff} [{Level:u3}] {Message:lj} {Properties} {ThreadId} {ThreadName}{NewLine}{Exception}", restrictedToMinimumLevel: LogEventLevel.Debug); } var logger = loggerConfig.CreateLogger();
对应简化后的JSON配置
{ "Serilog": { "Using": [ "Serilog.Sinks.File" ], "WriteTo": [ { "Name": "File", "Args": { "path": "Logs/EventsLog.txt", "rollingInterval": "Day", "retainedFileCountLimit": 31, "buffered": false, "outputTemplate": "{Timestamp:yyyy-MM-dd HH:mm:ss.fff} [{Level:u3}] {Message:lj} {NewLine}{Exception}", "restrictedToMinimumLevel": "Information" } } ], "Enrich": [ "FromLogContext", "WithMachineName", "WithThreadId", "WithThreadName" ] } }
方案二:用过滤器控制接收器触发
通过Serilog的过滤器功能,只有当全局最低级别为Debug时,才让Debug接收器处理事件。这种方式不需要修改JSON里的接收器列表,而是在代码中绑定级别开关做条件判断:
var levelSwitch = new LoggingLevelSwitch(LogEventLevel.Information); var config = new ConfigurationBuilder() .AddJsonFile("appsettings.json") .Build(); var loggerConfig = new LoggerConfiguration() .ReadFrom.Configuration(config) .MinimumLevel.ControlledBy(levelSwitch) // 给Debug接收器加条件:仅当全局级别允许Debug时才触发 .Filter.When( _ => levelSwitch.MinimumLevel <= LogEventLevel.Debug, cfg => cfg.WriteTo.File( path: "Logs/DebugLog.txt", rollingInterval: RollingInterval.Day, retainedFileCountLimit: 2, buffered: false, outputTemplate: "{Timestamp:yyyy-MM-dd HH:mm:ss.fff} [{Level:u3}] {Message:lj} {Properties} {ThreadId} {ThreadName}{NewLine}{Exception}", restrictedToMinimumLevel: LogEventLevel.Debug)); var logger = loggerConfig.CreateLogger();
如果想尽量用JSON配置实现过滤,可以借助Serilog.Expressions扩展(需要先安装该包),通过表达式检查全局级别:
{ "Serilog": { "Using": [ "Serilog.Sinks.File", "Serilog.Expressions" ], "WriteTo": [ { "Name": "File", "Args": { "path": "Logs/EventsLog.txt", "rollingInterval": "Day", "retainedFileCountLimit": 31, "buffered": false, "outputTemplate": "{Timestamp:yyyy-MM-dd HH:mm:ss.fff} [{Level:u3}] {Message:lj} {NewLine}{Exception}", "restrictedToMinimumLevel": "Information" } }, { "Name": "File", "Args": { "path": "Logs/DebugLog.txt", "rollingInterval": "Day", "retainedFileCountLimit": 2, "buffered": false, "outputTemplate": "{Timestamp:yyyy-MM-dd HH:mm:ss.fff} [{Level:u3}] {Message:lj} {Properties} {ThreadId} {ThreadName}{NewLine}{Exception}", "restrictedToMinimumLevel": "Debug" }, "Filter": { "Name": "ByIncludingOnly", "Args": { "expression": "MinimumLevel = 'Debug'" } } } ], "Enrich": [ "FromLogContext", "WithMachineName", "WithThreadId", "WithThreadName" ] } }
不过这种方式需要确保动态级别变化能被表达式正确识别,相对方案一复杂一些。
推荐方案一,逻辑简单直接,完全满足你“不记录Debug日志时就不生成Debug文件”的核心需求。
内容的提问来源于stack exchange,提问作者Sirosimo
相关产品推荐
相关产品推荐

