Database Logging with Serilog in an ASP.NET Core Application

What do we, developers, do when we want to use a framework we haven’t heard of before? 

Usually, we dig deeper and deeper to find some answers and sometimes we end up searching in too many places. 

This is what happened to me when I started implementing database logging with Serilog in ASP.NET Core, for one of our projects. 

In order to help other fellow developers in need, I decided to put the most important details about database logging using Serilog all together in this article.

What Is Logging and Why Is It Important?

Having an effective logging strategy can be vital for our applications. Logging usually provides useful data that can be often helpful in diagnosing failures, problem root causes analysis, and even do a performance review of the application.

What Should Be Logged?

Well, everything! We should log everything that provides useful data about the app and its behavior. For example:

Remember not to include sensitive data in logs!

A good practice is to customize error messages. Logs should contain some details to ease the investigations into the app’s failures:

Where Should We Keep the Logs?

One way to log data is using the Console. 

However, this isn’t the best approach in case of logs from the past need to be analyzed. In order to make this happen, logs should be stored in external files or databases. 

To make this happen, there are some third-party frameworks that could be used. 

One of them is Serilog.  

What is Serilog?

Serilog is a framework used to gather structured logs for an application and it is well suited to collecting and recording them in both files and databases. 

The main focus of this article will be configuring and implementing SQL server database logging with Serilog in ASP.NET Core.

Configuring Serilog

Serilog can be configured through the appsettings.json file. In this file, a new section named Serilog should be added. 

appsettings.json configuration for Serilog

Logging Levels Configuration

The “MinimumLevel” subsection determines the level at which log events are generated. This setting can be seen as a performance feature because it gives the ability to control which events actually generate logs. 

Any level lower than the minimum set won’t generate any logs.

Here are the existing levels:

If no minimum level is specified, then only “Information” level and higher will be processed.

MinimimLevel Serilog configuration from appsettings.json file

The “MinimumLevel” configuration can only be set to a single value, using the “Default” option. 

In our example, the minimum level is set to “Information”. If we want to capture “Error” level events too, we have to add the “Override” option and specify the “Error” level and, also, the logging source.

Database Configuration

To write logs to the database, the first step required is to install Serilog.Sinks. MSSqlServer package from NuGet.

In order to proceed with database logging with Serilog in ASP.NET Core, the first step required is to install Serilog.Sinks. MSSqlServer package from NuGet.

In the “Write To” subsection, we can set up the database connection string, along with the name of the table we want to create for logs. 

When creating the Logs table in the database, here are the options available:

By default, Logs table has the following structure:

Whether the Logs table is created using any of the options detailed above, all of these columns should exist in the table.

However, the Logs table can be customized by removing some of the default columns and adding custom ones. To do this, we have to add some extra details in the appsettings.json file.

WrtieTo database configuration in appsettings.json

To remove some of the default columns of the Logs table, the option “removeStandardColumns” is used.

In the example above, the default column “MessageTemplate” is no longer needed, so it has been removed.

To add custom columns, the option “customColumns” is used. Any column that suits the user’s needs can be added, with the mention that details like Column Name, Data Type and /or Data Length should be set.

Startup.cs Configuration

Serilog Logger configuration in Startup.cs file

In order to create a Logger, we use Serilog’s sinks, which are configured once, when the application first starts. The configuration must be done in the Configure function from Startup.cs file. 

Log.Logger accesses the global Serilog logger which can be later invoked using Log class and its static methods.

ReadFrom.Configuration(Configuration) helps us get the Serilog configuration we’ve done earlier in the appsettings.json file. 

How to Write Log Events

We can write Log events using Log class from Serilog in our app’s controllers. We can also dynamically add or remove some other properties to Log context, using enrichers.

For example, we can log the action “Order created” when a user successfully creates an order in our app, using: Serilog.Log.Information(“Order created”). We might also want to log the id of the user that created that order. We can do this by pushing a property into the Log context:  LogContext.PushProperty(“UserId”, user.Id). 

Log Information event in controller, using an enricher

In order to log errors, we could use an exceptions middleware. In this middleware, in catch() block, we can log error events using: Serilog.Log.Error(“Error”).Adding more details could be helpful.

Writing logs is an important step of application development that requires attention. In some cases, keeping the logs in the database is a good idea. 

A good logging strategy can be created just by following some basic rules.

Serilog may be suitable for one’s needs when logging events from the application. I found it very helpful in my case and relatively easy to implement after understanding all the steps that have to be followed.

If you give Serilog a try and have further questions, please leave them in the comments down below and I’ll do my best to help!

This content was originally published here.

Categories: Mobile App
vinova: