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

.NET 6后台服务启动崩溃时Serilog无法向Seq Sink发送日志

问题根源与修复方案

你的代码存在三个关键问题,导致catch块的日志无法输出到Seq:

  • 全局Log.Logger未初始化:catch块里调用Log.Logger.Error,但此时全局的Log.Logger还未被赋值为你创建的Serilog实例,默认是一个空日志实现,这条日志根本不会被发送。
  • try/catch覆盖范围不足:当前try仅包裹了Host.CreateDefaultBuilder的构建过程,但崩溃实际发生在Main方法的Build()或Run()阶段(即HostBuilder创建后的实例化、启动环节),这部分代码不在CreateHostBuilder的try块内,异常根本没被捕获。
  • logger被提前释放:你在using块中创建logger,同时在ConfigureLogging里设置了dispose: true,导致Host接管logger生命周期,但using块在CreateHostBuilder返回后就会释放logger,后续启动过程中即使出现异常,也没有可用的日志器记录。

修复后的代码示例

public sealed class Program
{
    public static void Main(string[] args)
    {
        // 提前初始化全局日志器,覆盖全启动流程的异常记录
        var environmentName = Environment.GetEnvironmentVariable("DOTNET_ENVIRONMENT");
        var configuration = new ConfigurationBuilder()
            .AddEnvironmentVariables() // 加载环境变量,确保能读取到Seq等配置
            .Build();

        var logger = new LoggerConfiguration()
            .Enrich.WithProperty("Application", configuration.GetValue<string>("ApplicationName"))
            .Enrich.WithProperty("ApplicationHost", System.Reflection.Assembly.GetExecutingAssembly().GetName().Name)
            .Enrich.WithProperty("Environment", environmentName)
            .Enrich.WithExceptionDetails(new DestructuringOptionsBuilder()
                .WithDefaultDestructurers()
                .WithDestructurers(new[] { new DbUpdateExceptionDestructurer() }))
            .ReadFrom.Configuration(configuration)
            .CreateLogger();

        // 设置全局日志器
        Log.Logger = logger;

        try
        {
            logger.Information("************ STARTING MY WORKER ************");
            CreateHostBuilder(args, logger).Build().Run();
        }
        catch (Exception ex)
        {
            logger.Fatal(ex, "Worker启动失败");
            throw;
        }
        finally
        {
            // 确保所有日志都被刷新到Seq
            Log.CloseAndFlush();
        }
    }

    private static IHostBuilder CreateHostBuilder(string[] args, ILogger logger)
    {
        return Host.CreateDefaultBuilder(args)
            .ConfigureServices((ctx, services) =>
            {
                services.AddSingleton(logger);
                services.AddHostedService<MyWorker>();
                services.AddSingleton<CustomClass>(); // 启用该修复解决崩溃问题
            })
            .ConfigureLogging((ctx, loggingBuilder) =>
            {
                loggingBuilder.ClearProviders();
                loggingBuilder.AddSerilog(logger, dispose: false); // 不让Host释放日志器,交由finally块处理
            });
    }
}

关键修改说明

  1. 全局日志器提前初始化:在Main方法开头就创建并设置Log.Logger,确保启动全流程的异常都能被捕获记录。
  2. 扩大try/catch范围:将Build()和Run()全部包裹在try块内,覆盖整个启动环节。
  3. 避免日志器提前释放:移除using块,改用finally块调用Log.CloseAndFlush()保证日志发送;同时在AddSerilog时设置dispose: false,避免Host提前释放日志器。
  4. 补充配置源:原ConfigurationBuilder未添加任何配置来源,导致可能无法读取Seq的连接配置,这里添加.AddEnvironmentVariables()适配Azure容器实例的环境变量配置方式。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.30 19:45:31