Introduction
In the dynamic world of application development, robust logging is a key component for understanding and troubleshooting software behavior. Serilog, a popular logging library for .NET, makes this process seamless. In this article, we'll explore how to implement external logging sources using Serilog for both APIs and Windows Services, providing a comprehensive solution for logging information.
Packages Needed
Before diving into implementation, ensure you have the necessary Serilog packages installed.
<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" />
Configuration of Serilog in API
To configure Serilog in your API, you need to add the following settings to your appsettings.json 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"
}
}
]
}
The %APP_BASE_DIRECTORY% placeholder will be read from app settings and updated at the startup of the service.
API Startup Configuration
In the startup of your API, configure Serilog as follows.
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();
Worker Class
Now, let's create a simple worker class that utilizes Serilog for logging.
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);
}
public override Task StopAsync(CancellationToken cancellationToken)
{
_logger.LogInformation("Stopping service [StopAsync]");
return base.StopAsync(cancellationToken);
}
}
With Serilog, logging for APIs and Windows Services becomes an effortless endeavor. By configuring Serilog to use external logging sources, you ensure that your application's behavior is well-documented and can be easily analyzed. Embrace the power of Serilog to enhance your logging strategy and make troubleshooting a breeze.