Introduction
La journalisation ne se limite pas à enregistrer des événements dans un fichier. Pour les applications Go fonctionnant dans des environnements de production à forte charge, les logs constituent la principale source d'informations de diagnostic. Sans une journalisation de qualité, la recherche d'erreurs devient un jeu de devinettes et la surveillance du système devient impossible.
Go offre au développeur des outils flexibles : du package intégré log aux puissantes bibliothèques tierces. Dans cet article, nous allons analyser les meilleures pratiques de journalisation en Go, apprendre à structurer les enregistrements, choisir les niveaux et éviter les erreurs typiques. Ce contenu sera utile aussi bien aux débutants qu'aux développeurs expérimentés souhaitant organiser leur approche de la journalisation.
La bibliothèque standard log : fonctionnalités de base et limitations
Le package log de la bibliothèque standard Go est le moyen le plus simple de commencer la journalisation. Il fournit un logger prêt à l'emploi qui écrit dans os.Stderr.
Exemple simple d'utilisation
package main
import ( "log")
func main() { log.Println("Application démarrée") log.Printf("Utilisateur %s connecté", "admin") log.Fatal("Erreur critique : base de données inaccessible")}La sortie ressemblera à ceci :
2023/10/27 14:35:12 Application démarrée2023/10/27 14:35:12 Utilisateur admin connecté2023/10/27 14:35:12 Erreur critique : base de données inaccessibleLimitations du logger standard
- Absence de niveaux de journalisation — pas de séparation entre Info, Warn, Error. Tous les messages sont écrits dans un seul flux.
- Mauvaise structure — l'enregistrement est une simple chaîne difficile à analyser automatiquement.
- Absence de contexte — impossible d'ajouter facilement un identifiant de requête ou d'utilisateur.
- Problèmes de performance — le logger standard bloque la goroutine lors de l'écriture, ce qui peut devenir un goulot d'étranglement.
Pour les petits utilitaires ou prototypes, log est tout à fait adapté. Mais pour les applications de production, il vaut mieux envisager des alternatives.
Journalisation structurée : pourquoi est-ce important ?
La journalisation structurée est une approche où chaque message représente un ensemble de paires "clé-valeur" (généralement au format JSON). Cela permet de :
- Analyser automatiquement les logs dans les systèmes de collecte (ELK, Splunk, Grafana Loki).
- Filtrer les enregistrements par n'importe quel attribut (niveau, service, ID de requête).
- Construire des tableaux de bord et des alertes basés sur des champs numériques.
Bibliothèques populaires pour la journalisation structurée
- logrus — l'une des premières et des plus populaires bibliothèques. Fournit des niveaux, du formatage (JSON, texte), des hooks pour envoyer les logs vers des systèmes externes. Cependant, elle a une consommation mémoire élevée.
- zerolog — bibliothèque axée sur la performance (zero allocation). Idéale pour les microservices et les systèmes à forte charge.
- zap — d'Uber. Très rapide, avec deux modes : SugaredLogger (pratique) et Logger (vitesse maximale).
- slog — package standard ajouté dans Go 1.21. Fournit une journalisation structurée "prête à l'emploi".
Exemple avec slog (Go 1.21+)
package main
import ( "log/slog" "os")
func main() { logger := slog.New(slog.NewJSONHandler(os.Stdout, nil)) logger.Info("Serveur démarré", "port", 8080, "env", "production") logger.Error("Erreur de connexion à la BD", "db", "postgres", "timeout", 5)}Sortie en JSON :
{"time":"2023-10-27T14:40:00.123Z","level":"INFO","msg":"Serveur démarré","port":8080,"env":"production"}{"time":"2023-10-27T14:40:01.456Z","level":"ERROR","msg":"Erreur de connexion à la BD","db":"postgres","t