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

.NET 6 Windows服务中Serilog在BackgroundService内无法日志输出

.NET 6 Windows服务无法生成Serilog日志的解决方案

问题分析

你的代码存在几个关键问题,导致服务运行时无法生成日志:

  • Serilog未与Host集成:直接初始化Log.Logger但未将其注册到Host日志系统,依赖注入的ILogger不会使用你配置的Serilog;静态Log.Information的输出路径也存在权限和路径上下文问题。
  • 相对路径上下文错误:Windows服务默认工作目录为C:\Windows\System32,用相对路径logs/log.txt会尝试在此目录创建文件,服务默认账户(LocalSystem)通常无写入权限。
  • 服务启动逻辑不完整:StartAsync未调用基类方法,会导致服务启动流程异常,且无日志记录异常信息。

修复步骤

1. 集成Serilog到Host构建流程

修改Program.cs,将Serilog注册为Host的日志提供器,并使用程序目录作为日志路径的基准:

using Serilog;
using System.IO;

public class Program
{
    public static void Main(string[] args)
    {
        // 获取程序所在绝对目录,规避服务工作目录问题
        var appRoot = AppContext.BaseDirectory;
        var logFilePath = Path.Combine(appRoot, "logs", "log.txt");

        Log.Logger = new LoggerConfiguration()
            .MinimumLevel.Debug()
            .WriteTo.File(logFilePath, rollingInterval: RollingInterval.Day, rollOnFileSizeLimit: true)
            .CreateLogger();

        try
        {
            var builder = Host.CreateDefaultBuilder(args)
                .ConfigureAppConfiguration(config =>
                {
                    // 用绝对路径加载配置文件,避免服务上下文找不到文件
                    config.AddJsonFile(Path.Combine(appRoot, "appsettings.json"), optional: false, reloadOnChange: true);
                })
                .ConfigureServices(services =>
                {
                    services.AddHostedService<WindowsBackgroundService>();
                    services.AddConnectionManagement();
                    services.AddSessionManagement();
                    services.AddTransient<IBLControllerFactory, BLControllerFactory>();
                    services.AddTransient<LoginHandler>();
                    services.AddHttpClient("123", (sp, client) =>
                    {
                        var config = sp.GetRequiredService<IConfiguration>();
                        client.Timeout = TimeSpan.FromMinutes(5);
                        client.DefaultRequestHeaders.Add("Origin", config.GetSection("123")["OriginHeader"]);
                        client.BaseAddress = new Uri(config.GetSection("123")["ApiBaseAddress"]);
                    }).AddHttpMessageHandler<LoginHandler>();
                })
                .UseWindowsService(opt => opt.ServiceName = "MES Server")
                .UseSerilog(); // 关键:将Serilog绑定到Host日志系统

            var host = builder.Build();
            host.Run();
        }
        catch (Exception ex)
        {
            Log.Fatal(ex, "服务启动失败");
        }
        finally
        {
            Log.CloseAndFlush();
        }
    }
}

2. 修复BackgroundService启动逻辑

确保调用基类StartAsync方法,同时优先使用注入的ILogger(已与Serilog集成):

public sealed class WindowsBackgroundService : BackgroundService
{
    private readonly ILogger<WindowsBackgroundService> _logger;
    
    public WindowsBackgroundService(ILogger<WindowsBackgroundService> logger)
    {
        _logger = logger;
    }
    
    public override async Task StartAsync(CancellationToken cancellationToken)
    {
        _logger.LogInformation("服务启动");
        await base.StartAsync(cancellationToken); // 必须调用基类方法,保证服务生命周期正常流转
    }

    protected override async Task ExecuteAsync(CancellationToken stoppingToken)
    {
        // 示例服务逻辑:循环输出运行日志
        while (!stoppingToken.IsCancellationRequested)
        {
            _logger.LogInformation("服务运行中,当前时间:{CurrentTime}", DateTime.Now);
            await Task.Delay(5000, stoppingToken);
        }
    }
}

3. 权限与部署检查

  • 手动在程序目录下创建logs文件夹,给服务运行账户(如LocalSystem)分配该文件夹的写入权限。
  • 安装服务时,确保服务的工作目录设置为程序所在路径(使用sc create命令时可通过binPath指定程序路径,或用Visual Studio发布工具自动配置)。

验证方式

  1. 重新发布程序,部署到目标机器。
  2. 安装并启动服务,查看程序目录下的logs文件夹是否生成日志文件。
  3. 若仍无日志,可查看Windows事件查看器的「应用程序」日志,排查服务启动的异常信息。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.16 06:20:55