A simple .NET Core logger implementation using Serilog library.
Introduction
Logging is very important part of any software application. It might be needed for various reasons. You might want to log e.g. for one or all of the following reasons:
- What your website users do on your website?
- Which page are popular on your site?
- Is some operation taking a longer time to complete? how much time?
- What run time error happened? what is the stack trace?
- Wanna capture some performance matrices?
- Other requirements/reasons etc.
In this article, I will share with you an implementation for this purpose, which is simple, light weight, extendable and can be very useful answering above mentioned questions. If your requirements are different, well, it will still be useful to look at this implementation or customize it as you see fit.
The idea is to share with you step by step implementation and that’s why I will write it in multiple parts and same time you can ask me if something is not clear to you.
We will be using Serilog library, but will also write our own wrapper logic. I will start simple by logging to text files and then later we will extend it to log to other sinks e.g. elastic-search.
In this part, we will setup the solution, install the nu-get packages and then start writing code for logging purposes. We will discuss some of the design ideas and will also see the LogDetail entity which is the log record we will be persisting and later querying.
Create ASP .NET Core Web API Project
I created a .NET Core web api project using visual studio default template. This comes with a WeatherController which we will use for our demo purposes.
Install Serilog nu-get Package
To install serialog, use nuget package window and select Serilog.Sinks.File. This will also install main Serilog nuget package as dependency in the solution.
Like many other libraries for .NET, Serilog provides diagnostic logging to files, the console, and elsewhere. It is easy to set up, has a clean API, and is portable between recent .NET platforms.
Another popular library which works in similar way and provide similar capabilities is NLOG.
Install NewtonsoftJson nuget Package
We will also install Newtonsoft.json nuget package. It will help us to do JSON serialization/deserialization.
Code Folder
I also created a folder to keep all the logging related code, so its in one place and easier to locate.
Log Types
First question, what we want to capture? can we classify those? or we just simply want to log a single line text message. Well in my case, I want to capture different kind of logs in this application. The main type of logs which I am interested in are as follows:
- Performance
- Usage
- Diagnostic
- Error
If you have some other types, feel free to add more as per your requirements.
Log Detail
Ok, we’ve identified the type of logs, but lets get into a little bit detail and think what log data we want to capture in our logs. You might have noticed from the log types, that we want to capture performance matrices i.e. how long a particular method execution takes. We also want to capture how many times a method was used and by whom it was used. If there were errors, we want to capture the stack trace and we would also like to log some of our diagnostic efforts or some other information etc.
For this purpose, I have create the following LogDetail class and this is the only LogDetail which will capture information for all type of logs we mentioned above.
We have to fill object of this class with appropriate information and then persist and query it later. We will see later how we will capture appropriate data for various log types from performance to diagnostic in this single type of entity.
Based on this requirement, here is our LogDetail model:
The class itself is very simple and feel free to add/delete properties as u see fit. If you are not sure about some of the properties at this point, don’t worry, those will become more clear, when we will hydrate this model with the actual data.
Where to Log
We know, what we want to log and now the question where to Log? Serilog has the notion of Sink which represent various type of destinations e.g. file, database etc.
We installed FileSink nuget package and this allows us to write these logs to text files and we will start from there.
I want to have separate log files, for different type of logs and also I want to have some configurability on the path for these files. I will use Environment variables for this purpose. Here is how these variables are setup in visual studio:
Notice the variable DIAGNOSTIC_ON set to true, this is an extra check which we can set if want to capture diagnostic logs or not. Now we have setup where we want these log files to be persisted.
Application Logger
Lets start by creating a class AppLogger.cs which will manage to write different type of logs. We will use ILogger interface from serilog for different type of loggers.
so, we are configuring different loggers in the constructor and providing the log file locations. When the constructor is called, all of the loggers will be property configured.
For each type of logger, we will introduce corresponding methods. This help keep code clean.
method names shall give you some idea about their work. We are passing LogDetail to these methods as well. Here is how the methods are implemented. You can check the code from repo and inspect it. Its very straight forward.
Custom Exception Class
I also created a CustomException class for error logging purpose. We will see later how this class will be used in our logging implementation.
Summary
Cool. We finished the part-1. Our work is not done yet but we have started and we have now some of the infrastructure code in place for our logger and in the next part, we will take from here and wire it up in our ASP .NET Core application pipeline. Till next time, Happy Coding.
References
- https://serilog.net/
- https://nlog-project.org/
Discover more from Hex Quote
Subscribe to get the latest posts sent to your email.