Common features in ASP.NET Core 2.1 WebApi: Logging

 

Introduction

Often overlooked, logging errors and other information in case of bug in the program is an essential feature in a Web API.

In this article we will see how to implement logging in a rolling file in an ASP.NET Core WebAPI with Serilog.

Serilog, 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.

Unlike other logging libraries, Serilog is built with powerful structured event data in mind.

Installation

Download these three packages:

PM> Install-Package Serilog.AspNetCore -Version 2.1.1
PM> Install-Package Serilog.Settings.Configuration -Version 3.0.1
PM> Install-Package Serilog.Sinks.RollingFile -Version 3.3.0

The Serilog.AspNetCore enables Serilog for ASP.NET Core, you have to add Serilog.Settings.Configuration if you need to enable configuration from appsettings.json.

Then Serilog.Sinks.RollingFile enables you to log into rolling files your logs.

Configuring your appsettings.json and Startup.cs

Step 1: Configuring appsettings.json

We chose rolling files to put our logs.

There are three big parts in the configuration

  1. Logging minimum level: In this example the minimum log level is “Information”
  2. Serilog itself: “WriteTo”, as you can see it’s an array, it means you can setup many Sinks (destination of the log), in our case “RollingFile”
  3. Properties: “Application” allows you to name your log if you want to know what log belongs to what application.

Example:

{
 "Serilog": {
    "MinimumLevel": "Information",
    "WriteTo": [
    {
       "Name": "RollingFile",
       "Args": {
          "pathFormat": "C:\\Temp\\log-{Date}.txt",
          "outputTemplate": "{Timestamp:yyyy-MM-dd HH:mm:ss.fff zzz} [{Level}] {Message}{NewLine}{Exception}"
       }
    }
   ],
   "Properties": {
      "Application": "Common feature in WebApi demo"
   }
 }
}

Once done we have to go to Startup.cs assigning this configuration to Serilog.

NB: Using settings in appsettings.json is not mandatory, you can build your configuraion by code, you can find examples here.

Step 2: Configuring Startup.cs

As we said before we need to read the configuration from appsettings.json in our example:

public Startup(IConfiguration configuration)
{
   // Init Serilog configuration
   Log.Logger = new LoggerConfiguration().ReadFrom.Configuration(configuration).CreateLogger();
   Configuration = configuration;
}

Then we need to add Serilog to the LoggerFactory in the Configure method:

public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
{
   // logging
   loggerFactory.AddSerilog();
   app.UseMvc();
 }

In fact Serilog override the default Microsoft Logger provided by the assembly: Microsoft.Extensions.Logging

Logging in action

Let’s create an action that catch an exception and logs it:

[Route("api/[controller]")]
[ApiController]
public class DemoExceptionController : ControllerBase
{
   private readonly ILogger<DemoExceptionController> _logger;

   public DemoExceptionController(ILogger<DemoExceptionController> logger)
   {
      _logger = logger;
   }

   [HttpGet]
   public IEnumerable<string> Get()
   {
      try
      {
         _logger.LogInformation("Could break here :(");
         throw new Exception("bohhhh very bad error");
      }
      catch (Exception e)
      {
         _logger.LogError(e, "It broke :(");
      }
      return new string[] { "value1", "value2" };
   }
}

Let’s see now what happen when this code is executed:

We can see the error log and more (Information) because we set it as minimum level.

Conclusion

This was an example of implementing logging in an ASP.NET Core WebAPI 🙂

Serilog provides many differents ways to log (Sinks), you can find the complete list here.

Serilog is very powerfull, you can also enrich your log easily with Enrichers, a great feature of Serilog!

Awesome right ? 😉