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

ASP.Net Core 5中Serilog静态Logger在IHost.Run()终止后无法输出日志及SelfLog启用问题

问题分析与解决方案

为什么IHost.Run()终止后日志无法输出?

核心原因在于你当前的Serilog集成方式中,IHost会接管全局Log.Logger的生命周期:当host.Run()终止(无论是正常退出还是异常崩溃),Host会释放所有注册的服务,其中就包括Serilog的日志提供者。这个过程会关闭或置无效全局的Log.Logger实例,导致后续catch/finally块中的日志调用完全失效。

另外你重复初始化了两次Logger:一次是CreateLogger()中的全局实例,一次是UseSerilog()中Host内部的实例,这也会导致生命周期管理混乱。

修复步骤

1. 保留全局Logger的生命周期

修改UseSerilog的调用,添加preserveStaticLogger: true参数,阻止Host在销毁时关闭全局的Log.Logger:

public static IHostBuilder CreateHostBuilder(string[] args) {
    BuildConfiguration();
    IHostBuilder hostBuilder = Host.CreateDefaultBuilder(args)
        // 添加preserveStaticLogger: true,保留全局Logger实例
        .UseSerilog((hostingContext, loggerConfiguration) => {
            loggerConfiguration.ReadFrom.Configuration(hostingContext.Configuration)
                .Enrich.With(new ThreadIdEnricher());
        }, preserveStaticLogger: true);
    return hostBuilder
        .UseWindowsService()
        .ConfigureWebHostDefaults(webBuilder => {
            webBuilder.UseConfiguration(Configuration);
            webBuilder.UseStartup<Startup>();
            webBuilder.UseHttpSys(options => { ... });
        });
}

2. 整合Logger初始化逻辑(可选但推荐)

移除独立的CreateLogger()方法,将全局Logger的初始化整合到UseSerilog中,避免重复配置:

public static IHostBuilder CreateHostBuilder(string[] args) {
    BuildConfiguration();
    IHostBuilder hostBuilder = Host.CreateDefaultBuilder(args)
        .UseSerilog((hostingContext, loggerConfiguration) => {
            // 初始化全局Logger
            Log.Logger = loggerConfiguration.ReadFrom.Configuration(hostingContext.Configuration)
                .Enrich.With(new ThreadIdEnricher())
                .CreateLogger();
            // 配置SelfLog
            Serilog.Debugging.SelfLog.Enable(msg => 
                File.AppendAllText("serilog-selflog.txt", $"{DateTime.Now:yyyy-MM-dd HH:mm:ss} - {msg}{Environment.NewLine}")
            );
            Serilog.Debugging.SelfLog.WriteLine("Serilog SelfLog initialized");
            Log.Information("Application startup ...");
        }, preserveStaticLogger: true);
    return hostBuilder
        .UseWindowsService()
        .ConfigureWebHostDefaults(webBuilder => {
            webBuilder.UseConfiguration(Configuration);
            webBuilder.UseStartup<Startup>();
            webBuilder.UseHttpSys(options => { ... });
        });
}

3. 优化SelfLog配置

你的SelfLog配置本身没问题,但之前因为Logger失效导致没有输出。现在可以将SelfLog输出到文件(而非仅控制台),更方便排查问题:

// 替换原Console输出,改为写入文件
Serilog.Debugging.SelfLog.Enable(msg => 
    File.AppendAllText("serilog-selflog.txt", $"{DateTime.Now:yyyy-MM-dd HH:mm:ss} - {msg}{Environment.NewLine}")
);

验证效果

修改完成后,当OptionsValidationException抛出并进入catch块时,Log.Fatal等日志会正常写入你的日志文件;finally块中的Log.CloseAndFlush()也能正确执行,确保所有缓存日志被写入。

内容的提问来源于stack exchange,提问作者sawie

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.30 03:44:12