Search code examples
c#windows-services.net-6.0serilog

Serilog doesn't work in BackgroundService


We have a .NET 6.0 Console Application that we want to run as a Windows Service, it works but it doesn't log. If I start it with Visual Studio or the EXE directly it works. I found some examples on how to configure Serilog but so far nothing has worked.

public class Program
{
    public static void Main(string[] args)
    {
        var builder = Host.CreateDefaultBuilder(args)
            .ConfigureAppConfiguration(configuration =>
            {
                configuration.AddJsonFile("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", (serviceProvider, client) =>
                {
                    var config = serviceProvider.GetService<IConfiguration>();

                    client.Timeout = TimeSpan.FromMinutes(5);
                    client.DefaultRequestHeaders.Add("Origin", config.GetSection("123").GetValue<string>("OriginHeader"));
                    client.BaseAddress = new Uri(config.GetSection("123").GetValue<string>("ApiBaseAddress"));
                }).AddHttpMessageHandler<LoginHandler>();
            })
            .UseWindowsService(lifetimeConfig =>
            {
                lifetimeConfig.ServiceName = "MES Server";
            });

        Log.Logger = new LoggerConfiguration()
            .MinimumLevel.Debug()
            .WriteTo.File("logs/log.txt", rollingInterval: RollingInterval.Day, rollOnFileSizeLimit: true)
            .CreateLogger();

        var host = builder.Build();

        host.Run();
    }
}



public sealed class WindowsBackgroundService : BackgroundService
{
    private readonly ILogger<WindowsBackgroundService> _logger;
    
    public WindowsBackgroundService(ILogger<WindowsBackgroundService> logger)
    {
        _logger = logger;
    }
    
    public override async Task StartAsync(CancellationToken cancellationToken)
    {
        Log.Information("Start service");
    }
}

Solution

  • logs/log.txt is a relative path that will resolve to a directory that your service won't likely have permission to access.

    Specifying an absolute path is the way to go. Windows service deployment can be a bit tedious - creating the target directory and ensuring your service user account has permission to access it will need to be part of the deployment process.