Utiliser Serilog avec DotNet Core 2.1

Utiliser Serilog avec DotNet Core 2.1 m’a permis de mettre facilement en place des logs dans une application DotNet Core. Par défaut, ils sont écrits dans un fichier texte mais pour l’exemple, j’ai choisi une base SQL Server.

Qu’est ce que Serilog ?

Serilog est une bibliothèque pour faciliter les logs applicatifs dans les applications DotNet et DotNet Core (1). Je ne vous ferai pas l’affront d’expliquer l’utilité de logger ce qu’il se passe dans vos applications.

Plusieurs puits (sinks) existent pour stocker les logs sur différents supports (fichier, SQL, noSQL, Splunk) (2).

La différence majeure par rapport aux autres bibliothèques de log est qu’elle propose un mécanisme permettant d’avoir des méta données sur les événements survenus. Cela permet d’exploiter plus facilement ces logs que des logs en texte brut.

Installation

Pour un projet DotNet Core de type application web ou API Web, il faut installer :

– Serilog.AspNetCore : le package spécifique à DotNet Core

– Serilog.Settings.Configuration : le package qui permet de passer la configuration depuis le fichier de configuration appsettings.json (3)

– Serilog.Sinks.MSSqlServer : le puit pour SQL Server (4)

Ensuite il faut nettoyer la solution du mécanisme de log par défaut. Ce dernier a le mérite d’exister mais on va le remplacer par quelque chose de sérieux. Voici ce à quoi ressemble un program.cs pour faire fonctionner Serilog. Il y a 3 étapes : la récupération de la configuration, la création du logger et l’enregistrement.

public class Program
    {
        public static IConfiguration Configuration { get; } = new ConfigurationBuilder()
        .SetBasePath(Directory.GetCurrentDirectory())
        .AddJsonFile("appsettings.json", optional: false, reloadOnChange: true)
        .AddJsonFile($"appsettings.{Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT") ?? "Production"}.json", optional: true)
        .Build();

        public static void Main(string[] args)
        {
            Log.Logger = new LoggerConfiguration()
            .ReadFrom.Configuration(Configuration)
            .CreateLogger();
            try
            {
                var host = CreateWebHostBuilder(args).Build();
                host.Run();
            }
            catch (Exception ex)
            {
                Log.Fatal(ex, "Error on host.Run()");
            }
            finally
            {
                Log.CloseAndFlush();
            }
        }

        public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
        WebHost.CreateDefaultBuilder(args)
        .UseStartup()
        .UseSerilog();
    }

Prochaine étape, la configuration. Pour cela il y a 2 options : configuration par code dans le program.cs ou configuration par le fichier de configuration appsettings.json. Dans la majorité des cas, cette seconde méthode est suffisante. Voici à quoi ressemble le JSON de configuration :

{
// configuration
  "Serilog": {
    "Using": [ "Serilog.Sinks.MSSqlServer" ],
    "MinimumLevel": "Information",
    "WriteTo": [
      {
        "Name": "MSSqlServer",
        "Args": {
          "connectionString": "Data Source=Server;Initial Catalog=DataBase;Trusted_Connection=True;MultipleActiveResultSets=true",
          "tableName": "Logs",
          "autoCreateSqlTable": true
        }
      }
    ]
  }
}

autoCreateSqlTable à true permet de créer automatiquement la table. Si vous voulez le faire à la main, le code SQL est disponible dans le depot Github (4).

MinimumLevel permet de spécifier quel niveau minimum doit être logger. Voici les niveaux d’importances des événements comme décrit par Sérilog (5):

  1. Verbose – tracing information and debugging minutiae; generally only switched on in unusual situations
  2. Debug – internal control flow and diagnostic state dumps to facilitate pinpointing of recognised problems
  3. Information – events of interest or that have relevance to outside observers; the default enabled minimum logging level
  4. Warning – indicators of possible issues or service/functionality degradation
  5. Error – indicating a failure within the application or connected system
  6. Fatal – critical errors causing complete failure of the application

Utilisation

Par défaut, Serilog va logger pleins d’événement en fonction du MinimumLevel spécifié dans la configuration. Pour ajouter ses propres traces, il faut passer par l’objet Log qui permet d’appeler la méthode associée au niveau de criticité voulu.

using Serilog;
// id is defined 

// writes a warning
Log.Warning($"Get item with id '{id}' not found");

Dorénavant, les logs de l’application sont consultables dans une table SQL.

Références :

(1) : https://serilog.net/

(2) : https://github.com/serilog/serilog/wiki/Provided-Sinks

(3) : https://github.com/serilog/serilog-settings-configuration

(4) : https://github.com/serilog/serilog-sinks-mssqlserver

(5) : https://github.com/serilog/serilog/wiki/Writing-Log-Events