Roger
Roger

Reputation: 2135

Serilog WriteTo.File() works in Console App but not in .net Core 3 Worker Service

The code below for init of a LoggerConfiguration() works in the Main() of a .net core 3 console application, but not in a worker service. With the console application the 'logs' folder and log.txt were created at run time. The folder was not created when running the service, so I tried multiple file paths ("c:\log.txt", "..\log.txt", "..\..\log.txt") none of which were created. Logging is showing in the Debug Console, but no log.txt file is created. No error is thrown, VS 2019 is running as administrator.

Referenced Packages:

<PackageReference Include="Serilog" Version="2.9.0" />
<PackageReference Include="Serilog.Sinks.Console" Version="3.1.1" />
<PackageReference Include="Serilog.Sinks.File" Version="4.1.0" />

Program.cs:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Serilog;

namespace WorkerService1
{
    public class Program
    {
        public static void Main(string[] args)
        {
            Log.Logger = new LoggerConfiguration()
                .MinimumLevel.Debug()
                .WriteTo.Console()
                .WriteTo.File("logs\\log.txt", rollingInterval: RollingInterval.Day)
                .CreateLogger();

            CreateHostBuilder(args).Build().Run();
        }

        public static IHostBuilder CreateHostBuilder(string[] args) =>
            Host.CreateDefaultBuilder(args)
                .ConfigureServices((hostContext, services) =>
                {
                    services.AddHostedService<Worker>();
                });
    }
}

Worker.cs:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;

namespace WorkerService1
{
    public class Worker : BackgroundService
    {
        private readonly ILogger<Worker> _logger;

        public Worker(ILogger<Worker> logger)
        {
            _logger = logger;
        }

        protected override async Task ExecuteAsync(CancellationToken stoppingToken)
        {
            while (!stoppingToken.IsCancellationRequested)
            {
                _logger.LogInformation("Worker running at: {time}", DateTimeOffset.Now);
                await Task.Delay(1000, stoppingToken);
            }
        }
    }
}

Upvotes: 2

Views: 10579

Answers (2)

Roger
Roger

Reputation: 2135

Comment from @christopher-rosales referenced .UseSerilog(). This requires an additional package, Serilog.Extensions.Hosting. The init of the Log.Logger in Main() did not work, so I added it to the CreateHostBuilder().

Program.cs:

using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Serilog;

namespace WorkerService1
{
    public class Program
    {
        public static void Main(string[] args)
        {
            Log.Logger = new LoggerConfiguration()
                .MinimumLevel.Debug()
                .WriteTo.Console()
                .WriteTo.File("logs\\log.txt", rollingInterval: RollingInterval.Day)
                .CreateLogger();

            CreateHostBuilder(args).Build().Run();
        }

        public static IHostBuilder CreateHostBuilder(string[] args) =>
            Host.CreateDefaultBuilder(args)
                .ConfigureServices((hostContext, services) =>
                {
                    services.AddHostedService<Worker>();
                })
                .UseSerilog();
    }
}

Upvotes: 1

Tom Regan
Tom Regan

Reputation: 3851

I fell victim to the same oddly-named NuGet package. You need to add Serilog.AspNetCore, even though it is a console application. For more information see this article: https://www.blinkingcaret.com/2018/02/14/net-core-console-logging/

Upvotes: 3

Related Questions