Software Development

Logging The backup plan- Serilog

Serilog is a sure shot analytical Logging library for .Net Applications. While it works wonderfully with Simple Apps, it results extraordinarily when the structures become composite and application becomes asynchronous.

In this article, we will be learning about Serilog, Its usage, Features, Its implementation in console App, .Net core 3.1 apps with logging targets Console, File, Rolling file, MongoDb, and Application Insight.

Git Repo link can be found at the end.

By the end, you will be sure enough to use Serilog in any of the new/Existing applications or small/enterprise-level applications.

So, Let’s START the learning process:

What is Logging

Logging is one of the most basic things that every application needs. It is fundamental to troubleshoot any application problems.

What is Serilog

Serilog is a Logging framework which makes it easy to send your logs to different places via simple configurations.

Installation

Go to View – Other windows – Package Manager Console.

Then run the below command.

Install-Package Serilog 

link to Nuget: https://www.nuget.org/packages/Serilog/

What are Sinks

Serilog itself does not save information anywhere. So we need to configure to save those logs. And, location is specified by using sinks.

Serilog provides sinks for writing log events to be stored in various formats. In easy words, sink is responsible for saving your logged information to places according to the selection made.

For example, if you use the console sink, then logs will be printed in the console window or if you choose the file sink, then logs will be saved in files. 

link to 86 provided sinks: https://github.com/serilog/serilog/wiki/Provided-Sinks

Sinks that we are going to use:

Install-Package Serilog.Sinks.ApplicationInsights 
Install-Package Serilog.Sinks.MongoDB 
Install-Package Serilog.Sinks.RollingFile
Install-Package Serilog.Sinks.Console 
Install-Package Serilog.Sinks.ColoredConsole

Structured logging

From the beginning, I am saying logging is very important, very useful for troubleshooting. But will it be useful if you can’t even understand(human eye/tool) written log? 
A popular quote demonstrating the purpose of saving the data.

The goal is to turn data into information and information into insight. 

Carly Fiorina

Here are some examples of structure logging:

If you write below code to log information given;

log.Debug("this is testing Serilog message");

It results in;

DEBUG 2020-05-18 16:17:58 – this is testing Serilog message

Output Formatting

As you noticed in the above result, time and level are also added. We also have the provision to change the format of the output, it is called output formatting.

Following fields can be used in a custom output template:

  • Exception
  • Level
  • Message
  • NewLine
  • Properties
  • Timestamp

An example is being given for your reference:

{Timestamp:yyyy-MM-dd} [{Level}] {Properties}{Message}{NewLine}{Exception}

Enrichment

Most logging frameworks provide some way to log additional context values across all logging statements. This is perfect for setting something like a UserId at the beginning for a request and having it included in every log statement. In Serilog, it is called Enrichments

Log events can be enriched with properties in various ways. A number of pre-built enrichers can be found here https://www.nuget.org/packages?q=serilog.Enrichers

Or Log Context can be used to push property. To set up a logging context use the below code.

new LoggerConfiguration()
    .Enrich.FromLogContext()

Properties can be added as below and will be added automatically.

 LogContext.PushProperty("userId",user.UserId)

Masking

In real-world application domains like banking, there are restrictions on what information should be logged. In those scenarios, we need some kind of provision to prevent those information to be logged. Let’s say, we have an account class having a password as private information.

public class Account
{
  public int Id { get; set; }
  public string Name { get; set; }
  public string Password { get; set; }
}

Password should not be logged if the whole object of the Account class is logged.

Here are are some of the useful Serilog Destructure nuget helpers:

  • Masking.Serilog
  • Destructurama.Attributed
  • Destructurama.ByIgnoring

For instance, we can use Destructurama.Attributed;

To setup it with Serilog, Install Nuget package as follows;

Install-Package Destructurama.Attributed

Then use the below code to setup masking;

 new LoggerConfiguration()
 .Destructure.UsingAttributes()

And then in the class, we can specify a LogMasked attribute to mask it as below.

public class Account
{
  public int Id { get; set; }
  public string Name { get; set; }
  [LogMasked]
  public string Password { get; set; }
}


Asp.net Core ConfigureServices method can be updated as follows (one way out of many);

public void ConfigureServices(IServiceCollection services)
{
   Log.Logger = new LoggerConfiguration()
              .Enrich.FromLogContext()
              .WriteTo.MongoDB("mongodb://localhost:27017/Serilog_Examples")
              .WriteTo.ApplicationInsights("9fxx6977-5797-4fba-9022-2275axxx5c66", TelemetryConverter.Traces, LogEventLevel.Verbose)
              .WriteTo.RollingFile("log-{Date}.txt", outputTemplate: "{Timestamp:yyyy-MM-dd} [{Level}] {Properties}{Message}{NewLine}{Exception}", shared: true)
              .CreateLogger();

  services.AddControllersWithViews();
}

Note: you have to install required packages for above code to work.

Check the Link to MongoDB community server Here

For Application Insight Key steps are being given here.

Summary 

We learnt the following major points about Serilog:

  1. What is Serilog
  2. Installation
  3. Serilog Sinks
  4. Structure logging
  5. Output formatting
  6. Serilog Enrichers
  7. Serilog Destructure(Masking) 

    Now, you can use the above information beneficially and Increase your knowledge.

Git repo link can be found here 

–Rakesh Kumar

Leave a Reply