Logging Brilliance in .NET Core Part 2 : Using of Serilog in Windows Service

.NET Core

Implement the External Logging Source to Logging Information of API and Windows Service - Serilog.

Packages need Serilog.AspNetCore.

<PackageReference Include="Serilog.AspNetCore" Version="8.0.0" />
<PackageReference Include="Serilog.Extensions.Hosting" Version="8.0.0" />
<PackageReference Include="Serilog.Settings.AppSettings" Version="2.2.2" />
<PackageReference Include="Serilog.Settings.Configuration" Version="8.0.0" />
<PackageReference Include="Serilog.Sinks.Console" Version="5.0.1" />
<PackageReference Include="Serilog.Sinks.File" Version="5.0.0" />

Confiuration of Serilog in API

Settings File

"LogBaseDirectory": "C:\\WindowsServiceLogs\\",
"Serilog": {
  "Using": [ "Serilog.Sinks.Console", "Serilog.Sinks.File" ],
  "MinimumLevel": "Debug",
  "WriteTo": [
    {
      "Name": "Console"
    },
    {
      "Name": "File",
      "Args": {
        "path": "%APP_BASE_DIRECTORY%/Logs/log-.txt",
        "rollingInterval": "Day"
      }
    }
  ]
}
/*
          %APP_BASE_DIRECTORY% - Will be read from App Settings and update in Startup of Service.
*/

Application / Worker Startup

using Serilog;

var host = Host.CreateDefaultBuilder(args)
    .UseWindowsService()
    .UseSerilog((context, services, configuration) => configuration
        .ReadFrom.Configuration(context.Configuration)
        .ReadFrom.Services(services))
    .ConfigureServices(services =>
    {
        IConfigurationRoot configuration = new ConfigurationBuilder()
            .SetBasePath(AppDomain.CurrentDomain.BaseDirectory)
            .AddJsonFile("appsettings.json")
            .Build();
        
        if (!Directory.Exists(configuration["LogBaseDirectory"]))
        {
            Directory.CreateDirectory(configuration["LogBaseDirectory"]);
        }

        Environment.SetEnvironmentVariable("APP_BASE_DIRECTORY", configuration["LogBaseDirectory"]);

        services.AddHostedService<SimpleWorker>();
    })
    .Build();

await host.RunAsync();

A Worker Class

 public class SimpleWorker : BackgroundService
 {
     private readonly ILogger<SimpleWorker> _logger; 

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

     protected override async Task ExecuteAsync(CancellationToken stoppingToken)
     {
         while (!stoppingToken.IsCancellationRequested)
         {
             _logger.LogInformation("Execute SimpleWorker -> [ExecuteAsync]");

             await Task.Delay(1000, stoppingToken);
         }
     }

     
     public override Task StartAsync(CancellationToken cancellationToken)
     {
         _logger.LogInformation("Starting service [StartAsync]");

         return base.StartAsync(cancellationToken);
     }

     /// <summary>
     /// Executes when the service is performing a graceful shutdown.
     /// </summary>
     /// <param name="cancellationToken"><see cref="CancellationToken"/></param>
     /// <returns><see cref="Task"/></returns>
     public override Task StopAsync(CancellationToken cancellationToken)
     {
         _logger.LogInformation("Stopping service [StopAsync]");

         return base.StopAsync(cancellationToken);
     }

 }

That's all, We configured all things. Just run the application, See the configured folder check for the log file and console too.

Output

Log file and console

Log

I will share the reference code in the comments section.