1. Introduction
Si la journalisation texte basique — c'est votre journal intime avec des notes "J'ai mangé aujourd'hui", alors la journalisation structurée transforme chaque entrée en une fiche avec des champs : {Date: ..., Événement: "Mangé", Calories: 500, Plat: "Viande rôtie"}. Ça veut dire que vous pouvez ensuite non seulement lire le journal, mais aussi construire un graphique des calories sur un mois, filtrer les événements par plat et savoir quand vous avez mangé trop tard.
Pourquoi le texte simple ne suffit-il pas ?
Avec du texte simple tout est simple... jusqu'à un certain point. Essayez de rassembler des statistiques sur les erreurs dans les logs, les volumes de ventes d'une boutique en ligne, la chaîne d'actions d'un utilisateur par son ID (par exemple 42), si toutes les données sont des pavés de texte. La journalisation structurée permet d'ajouter de l'analyse et même de l'IA aux logs. Avec elle on peut chercher des anomalies, construire des dashboards et réagir automatiquement aux problèmes.
Avantages
- Permet de logger non seulement des messages, mais aussi les données associées (champs/propriétés).
- Les logs peuvent être analysés automatiquement : compter, filtrer, générer des rapports.
- On utilise des formats standardisés, comme JSON, faciles à parser par des machines.
Serilog : qu'est-ce que c'est et pourquoi l'utiliser ?
Serilog (site officiel : serilog.net, documentation : github.com/serilog/serilog/wiki) est une bibliothèque populaire pour la journalisation structurée en .NET. Elle s'intègre très bien avec Microsoft.Extensions.Logging, supporte la sortie vers des dizaines de systèmes (fichier, console, Seq, ElasticSearch, Grafana, Azure, etc.), a un impact minimal sur la performance et est simple à configurer.
En quoi Serilog diffère du "simple logging" ?
- Structure : les logs sont des objets avec des champs, sur lesquels on peut filtrer (par ex. toutes les erreurs de l'utilisateur avec l'ID 42).
- Formats : sait écrire pas seulement du texte, mais aussi du JSON, du XML, pratique pour le traitement ultérieur.
- Flexibilité : beaucoup de packages-sinks prêts à envoyer les logs partout.
Structure d'une entrée de log avec Serilog
Regardons un log structuré avant d'écrire du code.
{
"Timestamp": "2024-06-22T10:23:45.123Z",
"Level": "Information",
"MessageTemplate": "L'utilisateur {UserId} s'est connecté",
"Properties": {
"UserId": 42,
"IpAddress": "127.0.0.1"
}
}
Même sans analyse avancée on comprend : il s'agit de l'utilisateur n°42 et de son adresse IP.
2. Installation et configuration de base de Serilog dans un projet C#
Étape 1. Installer les packages NuGet
Dans Rider/Visual Studio via le NuGet Package Manager installez :
- Serilog
- Serilog.Sinks.Console (sortie vers la console)
- Serilog.Extensions.Logging (pour l'intégration avec Microsoft.Extensions.Logging)
Via la ligne de commande :
dotnet add package Serilog
dotnet add package Serilog.Sinks.Console
Étape 2. Configuration minimale
Ajoutons la config dans Program.cs et écrivons le premier log.
using System;
using Serilog;
namespace MySuperApp
{
class Program
{
static void Main(string[] args)
{
// 1. Configuration basique de Serilog : sortie console
Log.Logger = new LoggerConfiguration()
.MinimumLevel.Debug()
.WriteTo.Console()
.CreateLogger();
// 2. Exemple de journalisation structurée
int userId = 42;
string ip = "127.0.0.1";
Log.Information("L'utilisateur {UserId} s'est connecté avec l'IP {IpAddress}", userId, ip);
Log.CloseAndFlush();
}
}
}
Dans la console on verra à peu près ceci :
[10:30:16 INF] L'utilisateur 42 s'est connecté avec l'IP 127.0.0.1
Ensuite il est facile d'envoyer la sortie dans un fichier JSON, Seq ou un autre système.
3. Formatage des logs : Message Template
Dans Serilog on utilise la syntaxe des templates au lieu de concaténer des chaînes :
Log.Information("Opération {Operation} sur le fichier {FileName}", "suppression", "test.txt");
Ce n'est pas qu'une jolie écriture — c'est de la journalisation structurée : les champs Operation et FileName seront présents dans l'entrée, accessibles pour filtrage et agrégation.
En quoi cela diffère-t-il de string.Format ?
string.Format("Opération {0} sur le fichier {1}", operation, fileName) concatène simplement la chaîne avec des placeholders {0}, {1}. Serilog crée des champs séparés avec lesquels on peut ensuite travailler analytiquement.
Configuration flexible : niveaux, filtres, différents "sinks"
Serilog peut écrire les logs simultanément à plusieurs endroits.
Log.Logger = new LoggerConfiguration()
.MinimumLevel.Debug()
.WriteTo.Console()
.WriteTo.File("log.txt", rollingInterval: RollingInterval.Day)
.CreateLogger();
Maintenant les logs sont écrits à la fois dans la console et dans un fichier avec rotation quotidienne.
4. Exemple
Supposons que nous faisons une application console "bloc-notes" qui permet de créer des entrées utilisateur. Ajoutons la journalisation structurée des actions.
using System;
using Serilog;
namespace NotesApp
{
class Program
{
static void Main(string[] args)
{
Log.Logger = new LoggerConfiguration()
.MinimumLevel.Information()
.WriteTo.Console()
.WriteTo.File("notes-log.json", rollingInterval: RollingInterval.Day,
formatter: new Serilog.Formatting.Json.JsonFormatter())
.CreateLogger();
Console.WriteLine("Entrez le nom d'utilisateur :");
string userName = Console.ReadLine();
Log.Information("L'utilisateur {UserName} a lancé l'application NotesApp", userName);
while (true)
{
Console.WriteLine("Entrez le texte de la note (ou tapez 'sortie') :");
string note = Console.ReadLine();
if (note == "sortie")
{
Log.Information("L'utilisateur {UserName} a quitté", userName);
break;
}
Log.Information("L'utilisateur {UserName} a créé une note : {NoteText}", userName, note);
}
Log.CloseAndFlush();
}
}
}
Commentaire :
Le log enregistre qui lance le programme, ce qui est saisi et quand il quitte. Dans le fichier notes-log.json chaque entrée est un objet JSON facile à analyser.
5. Détails utiles
Bonnes pratiques de la journalisation structurée
- N'abusez pas des niveaux Debug/Trace en production — utilisez Information et Warning judicieusement.
- Utilisez des paramètres nommés dans les templates au lieu de concaténer des chaînes.
- Ne logguez jamais de données sensibles (mots de passe, tokens, clés).
- Logguez les événements métier importants, pas seulement les erreurs et exceptions.
- Configurez la rotation et le nettoyage des logs pour éviter de remplir le disque.
Visualisation et analyse : Seq, Kibana, Application Insights
Serilog supporte de nombreux sinks — destinations où envoyer les logs.
| Sink | Courte description | Où c'est utilisé |
|---|---|---|
| Console | Directement dans la console | Développement, tests |
| File | Dans un fichier local ou réseau | Petits projets, dev |
| Seq | Interface web avec filtrage et dashboards | Entreprise, analytics |
| ElasticSearch | Puissant système de stockage et d'analyse | Grandes entreprises |
| Azure Application Insights | Monitoring cloud et télémétrie | Services fortement chargés sur Azure |
Seq (datalust.co/seq) — solution très populaire pour le développement et l'usage interne : filtrage pratique, recherche par champs et déploiement rapide.
Tables et visualisation
Ci-dessous — un petit tableau de ce qu'on peut logger de façon structurée :
| Ce qu'on loggue | À quoi ça ressemble dans Serilog | Exemple de valeur |
|---|---|---|
| ID utilisateur | |
123 |
| Action | |
"Suppression" |
| Erreur | |
"Module d'enregistrement" |
| Temps d'opération | {Elapsed:0.000} s | 1.234 |
| Nom de fichier | |
"report.pdf" |
Astuces et fonctionnalités additionnelles de Serilog
- Enrichers : ajoutent des propriétés à chaque log (par ex. .Enrich.WithMachineName()).
- Logs corrélés : ajoutez RequestId pour corréler une chaîne d'événements.
- Configuration via appsettings.json : pratique pour la production.
{
"Serilog": {
"MinimumLevel": "Debug",
"WriteTo": [
{ "Name": "Console" },
{ "Name": "File", "Args": { "path": "log.txt" } }
]
}
}
Advanced sinks : on peut envoyer des logs vers Slack, Telegram, par mail (mais attention à ne pas recevoir mille mails pour chaque erreur).
6. Partie pratique : intégration avec Microsoft.Extensions.Logging
En .NET on utilise souvent l'interface standard ILogger pour ne pas être lié à une librairie précise. Serilog peut être connecté en tant que provider.
Étape 1. Installer le package
dotnet add package Serilog.Extensions.Logging
Étape 2. Configuration
using Microsoft.Extensions.Logging;
using Serilog;
// ...
// Configurer Serilog comme d'habitude :
Log.Logger = new LoggerConfiguration()
.WriteTo.Console()
.CreateLogger();
// Maintenant on utilise Microsoft.Extensions.Logging
var loggerFactory = LoggerFactory.Create(builder =>
{
builder.AddSerilog();
});
ILogger<Program> logger = loggerFactory.CreateLogger<Program>();
logger.LogInformation("Message de test : {TestValue}", 123);
// N'oubliez pas de fermer :
Log.CloseAndFlush();
Commentaire :
Désormais tout votre code utilisant ILogger<T> est indépendant du provider — si vous voulez vous pouvez basculer vers NLog ou Log4Net.
7. Erreurs typiques en travaillant avec Serilog
Surcharge des logs : si vous logguez tout, l'information utile sera difficile à trouver.
Logger les exceptions comme du texte : utilisez la surcharge avec l'exception — ainsi la structure de l'erreur sera incluse dans le log.
try
{
// some code
}
catch (Exception ex)
{
Log.Error(ex, "Une erreur s'est produite lors de l'exécution de la requête");
}
Abus de configuration : ne transformez pas la configuration en dépotoir — n'ajoutez que les sinks et niveaux nécessaires.
GO TO FULL VERSION