.NET5中Serilog如何通过LevelSwitch动态调整各Sink的最低日志级别
问题原因
你报错是因为restrictedToMinimumLevel参数仅接受Serilog.Events.LogEventLevel枚举值,不支持ControlledBy绑定LevelSwitch的语法,你传入对象结构时配置绑定系统无法将其转为枚举类型,因此抛出构造函数缺失异常。
解决方案
方案1:使用Sink原生支持的levelSwitch参数(推荐)
绝大多数官方Serilog Sink(包括Console、File等)都提供了levelSwitch配置参数,可直接绑定你预先定义的LevelSwitch,无需通过restrictedToMinimumLevel配置。
首先修改appsettings.{env}.json配置:
{ "Serilog": { "Using": [ "Serilog.Sinks.Console", "Serilog.Sinks.File" ], "LevelSwitches": { "$baseSwitch": "Verbose", "$consoleSwitch": "Warning", "$fileSwitch": "Information" // 可以给每个Sink单独定义开关 }, "MinimumLevel": { "ControlledBy": "$baseSwitch" }, "WriteTo": [ { "Name": "Console", "Args": { "levelSwitch": "$consoleSwitch", // 直接绑定开关 "outputTemplate": "{Timestamp} [{Level:u3}] [{LogSource}]: {Message} {Properties}{NewLine}{Exception}" } }, { "Name": "File", "Args": { "path": "Logs/log.txt", "levelSwitch": "$fileSwitch" // 文件Sink也可单独绑定开关 } } ], "Enrich": [ "FromLogContext" ] } }
然后确保配置加载时开启热重载,修改Program.cs中的配置加载逻辑:
public static IHostBuilder CreateHostBuilder(string[] args) => Host.CreateDefaultBuilder(args) .ConfigureAppConfiguration((hostingContext, config) => { var env = hostingContext.HostingEnvironment; // 确保json配置开启reloadOnChange config.AddJsonFile("appsettings.json", optional: false, reloadOnChange: true) .AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true, reloadOnChange: true); }) .UseSerilog((hostingContext, loggerConfiguration) => { // 从配置加载Serilog设置 loggerConfiguration.ReadFrom.Configuration(hostingContext.Configuration); }) .ConfigureWebHostDefaults(webBuilder => { webBuilder.UseStartup<Startup>(); });
方案2:通用Filter适配方案(兼容不支持levelSwitch的第三方Sink)
如果使用的第三方Sink未提供levelSwitch参数,可以通过全局Filter绑定LevelSwitch实现级别控制:
{ "Name": "YourCustomSink", "Filter": { "ControlledBy": "$customSinkSwitch" }, "Args": { // 其他Sink参数 } }
运行时修改日志级别
如果需要代码层面动态修改级别,只需将定义的LevelSwitch实例注册到DI容器或者存储到全局变量中,修改其MinimumLevel属性即可立即生效,无需重启应用:
// 示例:修改Console输出的最低级别为Information var consoleSwitch = serviceProvider.GetRequiredService<LoggingLevelSwitch>(); // 提前注册到DI即可 consoleSwitch.MinimumLevel = LogEventLevel.Information;
注意事项
- 确保
Serilog.Settings.ConfigurationNuGet包版本 >= 3.3.0,低于该版本不支持Sink参数直接绑定LevelSwitch - 根节点的MinimumLevel是全局过滤级别,Sink的级别如果低于全局级别,会被全局过滤拦截,建议全局级别设为最低的Verbose,由各Sink的开关单独控制输出级别
内容的提问来源于stack exchange,提问作者maradev21
相关产品推荐
相关产品推荐

