使用Serilog的MinimumLevel.Override无法过滤指定命名空间的LogEvents?
Serilog日志级别覆盖规则不生效问题
我配置了Serilog日志,代码如下:
loggerConfiguration .ReadFrom.Configuration(configuration) .MinimumLevel.Is(GetLoggingLevel(configuration.GetSection($"{Constants.LoggingSectionName}:MinimumLevel"))) .MinimumLevel.Override("Microsoft.AspNetCore.Hosting.Diagnostics", LogEventLevel.Warning) .MinimumLevel.Override("Microsoft.Hosting.Lifetime", LogEventLevel.Warning) .Enrich.FromLogContext() .WriteTo.Console(outputTemplate: Constants.Template, theme: AnsiConsoleTheme.Code, levelSwitch: HasLevelSwitches(configuration) ? new Serilog.Core.LoggingLevelSwitch(GetLoggingLevel(GetDictionaryOfSettings(configuration, "LevelSwitches")["$consoleLogLevel"])) : null) .WriteTo.File(path: configuration.GetSection($"{Constants.LoggingSectionName}:FilePath").Value, rollingInterval: RollingInterval.Day, retainedFileCountLimit: GetIntSafe(configuration.GetSection($"{Constants.LoggingSectionName}:RetainedFileCountLimit"), 31), shared: true, outputTemplate: Constants.Template, fileSizeLimitBytes: ConvertMegaBytesToBytesSafe(configuration.GetSection($"{Constants.LoggingSectionName}:FileSizeLimitMegaBytes"), 500L), rollOnFileSizeLimit: true, flushToDiskInterval: GetTimeSpanFromSecondsSafe(configuration.GetSection($"{Constants.LoggingSectionName}:FlushToDiskIntervalSeconds")), levelSwitch: HasLevelSwitches(configuration) ? new Serilog.Core.LoggingLevelSwitch(GetLoggingLevel(GetDictionaryOfSettings(configuration, "LevelSwitches")["$fileLogLevel"])) : null);
全局最低日志级别设为Information,我通过MinimumLevel.Override指定了两个命名空间仅输出Warning及以上级别日志,但运行时仍持续看到这两个命名空间的低级别日志事件。
更新1
尝试了更宽泛的命名空间覆盖规则,问题依旧:
.MinimumLevel.Override("Microsoft", LogEventLevel.Warning) .MinimumLevel.Override("System", LogEventLevel.Warning)
解决方案
1. 调整配置读取顺序
你当前先调用.ReadFrom.Configuration(configuration)加载配置文件设置,后续代码中的MinimumLevel.Override会被配置文件中的规则覆盖。调整顺序,先设置代码中的覆盖规则,再读取配置文件:
loggerConfiguration .MinimumLevel.Is(GetLoggingLevel(configuration.GetSection($"{Constants.LoggingSectionName}:MinimumLevel"))) // 先设置命名空间覆盖规则 .MinimumLevel.Override("Microsoft.AspNetCore.Hosting.Diagnostics", LogEventLevel.Warning) .MinimumLevel.Override("Microsoft.Hosting.Lifetime", LogEventLevel.Warning) // 再读取配置文件 .ReadFrom.Configuration(configuration) .Enrich.FromLogContext() // 其余Sink配置保持不变 .WriteTo.Console(...) .WriteTo.File(...);
2. 处理LevelSwitch的优先级冲突
你的Console和File Sink使用了levelSwitch,该开关的优先级高于全局MinimumLevel.Override。如果$consoleLogLevel或$fileLogLevel设为Information,Sink会直接输出该级别及以上日志,忽略命名空间过滤。
- 若不需要动态调整级别:直接移除
levelSwitch参数,让全局Override规则生效。 - 若要保留LevelSwitch并应用命名空间过滤:给Sink添加
filter逻辑,手动判断日志级别和来源:
// Console Sink示例 .WriteTo.Console( outputTemplate: Constants.Template, theme: AnsiConsoleTheme.Code, levelSwitch: levelSwitch, filter: logEvent => { var sourceContext = logEvent.Properties.TryGetValue("SourceContext", out var sc) ? sc.ToString().Trim('"') : string.Empty; // 针对目标命名空间强制使用Warning级别 if (sourceContext.StartsWith("Microsoft.AspNetCore.Hosting.Diagnostics") || sourceContext.StartsWith("Microsoft.Hosting.Lifetime")) { return logEvent.Level >= LogEventLevel.Warning; } // 其他日志使用LevelSwitch设置的级别 return logEvent.Level >= levelSwitch.MinimumLevel; } )
3. 检查配置文件冲突
打开你的配置文件(如appsettings.json),确认是否存在针对这些命名空间的日志级别设置,比如:
"Logging": { "LogLevel": { "Microsoft.AspNetCore.Hosting.Diagnostics": "Information", "Microsoft.Hosting.Lifetime": "Information" } }
若存在此类配置,会覆盖代码中的Override规则,需删除或修改为Warning级别。
内容的提问来源于stack exchange,提问作者IbrarMumtaz
相关产品推荐
相关产品推荐

