.NET Host ApplicationBuilder中如何关联IOptionsMonitor与Serilog日志级别开关
.NET HostApplicationBuilder 实现Serilog日志级别动态同步
核心实现思路
通过工具包封装扩展方法,利用IOptionsMonitor<LoggingOptions>监控appsettings.json中Logging配置节的变更,自动同步到Serilog的LoggingLevelSwitch.MinimumLevel。无需应用开发者编写额外回调注册或启停代码,仅需调用工具包的扩展方法即可。
工具包封装代码
using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; using Microsoft.Extensions.Options; using Serilog; using Serilog.Core; using Serilog.Events; namespace YourToolkitNamespace; public static class HostApplicationBuilderSerilogSyncExtensions { // 扩展方法,直接绑定到HostApplicationBuilder public static HostApplicationBuilder SyncSerilogLevelWithConfig(this HostApplicationBuilder builder) { // 显式绑定Logging配置到LoggingOptions(默认Host已自动处理,此处确保配置生效) builder.Services.Configure<LoggingOptions>(builder.Configuration.GetSection("Logging")); // 宿主构建完成后,自动注册变更回调 builder.BuildHostCompleted += (_, eventArgs) => { var host = eventArgs.Host; var optionsMonitor = host.Services.GetRequiredService<IOptionsMonitor<LoggingOptions>>(); var levelSwitch = host.Services.GetRequiredService<LoggingLevelSwitch>(); // 初始同步:确保启动时日志级别与配置一致 UpdateLogLevel(optionsMonitor.CurrentValue, levelSwitch); // 配置变更时自动同步 optionsMonitor.OnChange((options, _) => UpdateLogLevel(options, levelSwitch)); }; return builder; } // 同步日志级别的核心逻辑 private static void UpdateLogLevel(LoggingOptions options, LoggingLevelSwitch levelSwitch) { if (options.LogLevel.TryGetValue("Default", out var configLevel) && Enum.TryParse<LogEventLevel>(configLevel, true, out var serilogLevel)) { levelSwitch.MinimumLevel = serilogLevel; } } } // 对应appsettings.json中Logging节点的模型类 public class LoggingOptions { public Dictionary<string, string> LogLevel { get; set; } = new(StringComparer.OrdinalIgnoreCase); }
应用开发者使用方式
var builder = Host.CreateApplicationBuilder(args); // 1. 创建LoggingLevelSwitch并注册为单例 var levelSwitch = new LoggingLevelSwitch(); builder.Services.AddSingleton(levelSwitch); // 2. 配置Serilog,使用日志级别开关 builder.Services.AddSerilog(config => { config.MinimumLevel.ControlledBy(levelSwitch) .WriteTo.Console(); }); // 3. 调用工具包扩展方法,自动开启配置同步 builder.SyncSerilogLevelWithConfig(); var host = builder.Build(); host.Run();
关键说明
- 无需额外服务注册:仅依赖.NET默认的
IOptionsMonitor<LoggingOptions>单例和Serilog的LoggingLevelSwitch,无需新增自定义单例服务。 - 自动监控与同步:
BuildHostCompleted事件确保宿主构建完成后才获取服务实例,避免服务未初始化的问题;IOptionsMonitor.OnChange自动捕获配置文件变更并同步日志级别。 - 零侵入开发:应用开发者只需调用工具包的扩展方法,无需编写任何配置变更的处理逻辑。
内容的提问来源于stack exchange,提问作者Kjell Rilbe
相关产品推荐
相关产品推荐

