What is Serilog?
Serilog is a .NET library that provides diagnostic logging to files, the console, and almost everywhere you would like.
Serilog can be used in classic .NET Framework applications and for applications running on the latest and greatest .NET 6.
One of the biggest strengths of Serilog is that it has been built with structured logging in mind.
You can find more information on Serilog’s website.
Why do I use Serilog?
Now that we know more about Serilog let me tell you my personal experience with it. I used Serilog in a few applications with different logging requirements, and I was always satisfied with my results.
I cannot speak much about performance because I don’t work with large distributed ultra-scalable applications, but the performance was never an issue in my use cases.
I like Serilog’s simple integration into .NET applications, the ease of use, how simple you can start, and what more advanced features are available and can be used later in your journey.
Let’s create an application and integrate Serilog.
Creating an ASP.NET Core Web API Project
In Visual Studio 2022, we create a new project based on the ASP.NET Core Web API project template.
We choose SerilogDemo as the project name and, on the next dialog page, we stick with the defaults and use .NET 6.
We click on Create and wait until Visual Studio generated the project for us.
Install Serilog
Installing Serilog is simple. First, we open the NuGet Package Manager and search for the Serilog.AspNetCore package and install the latest stable version.
After a few seconds, Serilog is installed.
Configure Serilog-Logging in Program.cs
Next, let’s integrate Serilog into our application by registering it as a logging provider.
var logger = new LoggerConfiguration()
.ReadFrom.Configuration(builder.Configuration)
.Enrich.FromLogContext()
.CreateLogger();
builder.Logging.ClearProviders();
builder.Logging.AddSerilog(logger);
I insert a code snippet that defines a new LoggerConfiguration. We configure the configuration to read the application configuration from the application builder. We also enrich Serilog with the log context.
Next, we clear all existing logging providers. The WebApplication builder adds, for example, the console logging provider, and we want to get rid of that.
Last but not least, we add Serilog to the logging providers for our application and provide the configured LoggerConfiguration object as its sole argument.
Configure Serilog in appsettings.json
We configured the logger to use the settings from the application configuration. Let’s open the appsettings.json file and configure Serilog.
{
“Logging”: {
“LogLevel”: {
“Default”: “Information”,
“Microsoft.AspNetCore”: “Warning”
}
},
“AllowedHosts”: “*”,
“Serilog”: {
“Using”: [ “Serilog.Sinks.File” ],
“MinimumLevel”: {
“Default”: “Information”
},
“WriteTo”: [
{
“Name”: “File”,
“Args”: {
“path”: “../logs/webapi-.log”,
“rollingInterval”: “Day”,
“outputTemplate”: “[{Timestamp:yyyy-MM-dd HH:mm:ss.fff zzz} {CorrelationId} {Level:u3}] {Username} {Message:lj}{NewLine}{Exception}”
}
}
]
}
}
I insert a sample configuration. Let’s take a look at it. First, there is the using property where we define an array of log targets. In Serilog, log targets are called sinks. We configure an array with a single sink, the Serilog.Sinks.File sink.
Next, we can configure log levels and, more importantly, the WriteTo section. In the WriteTo section, we configure information for the File sink. The name property with the value “File” defines that the property provided in the “Args” property will be used for the File sink.
We configure the path where our log file should be written. The rollingInterval property defines when a new file should be created. And the outputTemplate defines the structure of the log output for each log statement.
Add a Log Statement in the WeatherForecastController
Now that Serilog is configured, we open the WeatherForecastController class and insert a log statement in the Get method.
_logger.LogInformation(“Weather Forecast executing…”);
Now let’s start the application.
Sending a Get Request
We use Swagger to send a simple get request to the WeatherForecast controller. Open the entry in the endpoints list and click on the “Try it out” button. We click the big blue Execute button to send a request.
We receive an array with weather data.
However, let’s close the application and look at the log files.
Exploring the Log File
We open the project directory and open the logs folder. The file name contains the prefix we configured in the appsettings.json file, and the part after the dash is the current day.
With the current configuration, Serilog creates a separate file for every day. We collect all the log statements for any given day in its file.
[2022-01-22 17:15:54.496 +01:00 INF] Now listening on: https://localhost:7068
[2022-01-22 17:15:54.520 +01:00 INF] Now listening on: http://localhost:5068
[2022-01-22 17:15:54.524 +01:00 INF] Application started. Press Ctrl+C to shut down.
[2022-01-22 17:15:54.524 +01:00 INF] Hosting environment: Development
[…]
[2022-01-22 17:16:06.353 +01:00 INF] Request starting HTTP/2 GET https://localhost:7068/WeatherForecast – –
[2022-01-22 17:16:06.359 +01:00 INF] Executing endpoint ‘SerilogDemo.Controllers.WeatherForecastController.Get (SerilogDemo)’
[2022-01-22 17:16:06.367 +01:00 INF] Route matched with {action = “Get”, controller = “WeatherForecast”}. Executing controller action with signature System.Collections.Generic.IEnumerable`1[SerilogDemo.WeatherForecast] Get() on controller SerilogDemo.Controllers.WeatherForecastController (SerilogDemo).
[2022-01-22 17:16:06.369 +01:00 INF] Weather Forecast executing…
[2022-01-22 17:16:06.371 +01:00 INF] Executing ObjectResult, writing value of type ‘SerilogDemo.WeatherForecast[]’.
[2022-01-22 17:16:06.380 +01:00 INF] Executed action SerilogDemo.Controllers.WeatherForecastController.Get (SerilogDemo) in 9.1166ms
[2022-01-22 17:16:06.381 +01:00 INF] Executed endpoint ‘SerilogDemo.Controllers.WeatherForecastController.Get (SerilogDemo)’
[2022-01-22 17:16:06.382 +01:00 INF] Request finished HTTP/2 GET https://localhost:7068/WeatherForecast – – – 200 – application/json;+charset=utf-8 28.4984ms
Let’s open the file and scroll through it. We can see a timestamp and our log statement that we added to the WeatherForecastController class.
Provided Sinks
Now that we learned about the basics of Serilog and integrated it into our application let’s look at the provided sinks.
As we can see, there are sinks for popular cloud providers, including Amazon CloudWatch, Azure Analytics, and many other cloud services. There are also sinks for the Windows event log, Microsoft Teams, and other interesting log targets.
Additional features
- You can enrich Serilog with additional information such as a SessionID or a web RequestID.
- You can configure the output format with placeholders and configure JSON instead of plain text output.
- You can explore all the additional opportunities Serilog provides in the Wiki on the GitHub project site.