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

.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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.02 02:52:45