Introduction
When working on our local development environment, we have the convenience of using breakpoints and debugging tools to closely examine our code and understand its behavior. However, once we deploy the application to other environments like staging or production, these debugging capabilities are not readily available. In such cases, we rely heavily on logging.
Logging serves as a method to monitor and record events within our applications. It allows us to generate logs for informational insights or to trace and identify errors that occur during application execution.
What is Serilog?
Serilog is an easy-to-use diagnostic logging library designed for .NET applications. It is compatible with all recent .NET versions and can be customized to log to various destinations such as files, the console, and external providers.
Installing and Configuring Serilog
We can install Serilog via the command line or the NuGet package manager.
dotnet add package Serilog
Once installed, we can setup Serilog at application startup, typically in the program.cs, using the Serilog.Log static class:
using Serilog;
Log.Logger = new LoggerConfiguration()
.CreateLogger();
Currently, our configured logger does not store logs anywhere. To view our logs, we need to set up sinks. Let’s explore what sinks are.
Serilog Sinks
Serilog utilizes sinks to capture events and store them in an external format. When setting up Serilog, it’s essential to define these sinks; otherwise, events will not be logged. Serilog sinks are accessible through NuGet packages. For instance, options include the Console sink, which outputs log data to the console, and the File sink, which saves log events to a file. These sinks can be incorporated into our application either through the command line or the NuGet package manager.
dotnet add package Serilog.Sinks.Console
dotnet add package Serilog.Sinks.File
We can now configure our logger to write to the desired sinks:
Log.Logger = new LoggerConfiguration()
.WriteTo.Console()
.WriteTo.File("log.txt",
rollingInterval: RollingInterval.Day)
.CreateLogger();
Using WriteTo.Console() directs log events to be displayed on the console.
For WriteTo.File(), it’s necessary to define the log file’s location. Additional parameters such as rollingInterval can also be configured; for example, specifying daily intervals creates a new log file each day.
Log Level Event
Serilog offers six distinct log levels:
- Verbose: The most detailed level, capturing all trace events. Typically, this level is not enabled in production environments due to its high verbosity.
- Debug: Used for logging internal application events that are not visible externally. This level helps in debugging the application’s internal workings.
- Information: Logs details about the normal operations of the application, providing general information about its processes.
- Warning: Captures events that deviate from the application’s normal behaviour, indicating potential issues that need attention.
- Error: Used to log events where functionalities have failed. These events are critical and require prompt attention.
- Fatal: The most severe level, used for logging critical events that could cause the application to crash. These events demand immediate attention.
We can specify the minimum level at which we want to capture events while configuring our logger.
Log.Logger = new LoggerConfiguration()
.MinimumLevel.Information()
.WriteTo.Console()
.WriteTo.File("log.txt",
rollingInterval: RollingInterval.Day,
rollOnFileSizeLimit: true)
.CreateLogger();
If the minimum log level is not specified, Serilog will use Information as the default level.
Using the Logger
The simplest way to use the logged in our project is through the global log class.
[Route("api/[controller]")]
[ApiController]
public class TestController : ControllerBase
{
[HttpPost("test-logger")]
public IActionResult TestLogger()
{
Log.Information("This log is from the global Log class");
return Ok();
}
}
Writing Logs to Seq
Seq is a self-hosted server designed for searching and analyzing structured logs. It captures events as fully structured JSON data, allowing for easy searching and filtering with various parameters. This method offers a more efficient way to access and interpret logs compared to traditional file-based logging. Seq can be installed on a local machine or on a Windows or Linux server.
You can download Seq from the official website https://datalust.co/download and follow the instruction guide to install it on your local machine.
Installing Seq using docker
You can find the official image of Seq on docker hub on this link https://hub.docker.com/r/datalust/seq.
Run the docker pull command to download the docker image for Seq.
docker pull datalust/seq
To run the docker container, execute the following command.
docker run --name seq -d --restart unless-stopped -e ACCEPT_EULA=Y -p 5341:80 datalust/seq:latest
This will run an initially-unsecured Seq instance with container-local storage and all services on port 5341.
We are now ready to configure our logger to write to Seq. To do this we have to install the Seq sink.
dotnet add package Serilog.Sinks.Seq
In our logger configuration we can now write to Seq and provide the Seq URL:
Log.Logger = new LoggerConfiguration()
.MinimumLevel.Information()
.WriteTo.Seq("http://localhost:5341")
.CreateLogger();
Log.Information("Starting up application");
Conclusion
Logging is a crucial aspect of our applications. It helps save time in diagnosing production issues and provides essential information for monitoring. We have explored how to integrate Serilog logging with a robust search and analysis server like Seq.