.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发布工具自动配置)。
验证方式
- 重新发布程序,部署到目标机器。
- 安装并启动服务,查看程序目录下的
logs文件夹是否生成日志文件。 - 若仍无日志,可查看Windows事件查看器的「应用程序」日志,排查服务启动的异常信息。
内容的提问来源于stack exchange,提问作者BluePalmTree
相关产品推荐
相关产品推荐

