Logging structuré
Formats, niveaux, centralisation et bonnes pratiques pour le logging dans les systèmes distribués.
Pourquoi le logging structuré ?
Dans un système monolithique, lire des logs en texte brut peut suffire. Mais dans une architecture distribuée comptant des dizaines de services, les logs non structurés deviennent ingérables. Le logging structuré — où chaque entrée est un objet doté de champs bien définis — constitue le socle qui permet de rechercher, filtrer et corréler les événements à grande échelle.
Formats de log
JSON comme standard
Le format le plus répandu pour les logs structurés est JSON. Chaque ligne de log est un objet aux champs cohérents :
{
"timestamp": "2024-01-15T10:30:00.123Z",
"level": "INFO",
"service": "order-service",
"traceId": "abc123def456",
"message": "Orden creada exitosamente",
"orderId": "ORD-789",
"userId": "USR-456",
"duration_ms": 145
}
Champs essentiels
Tout log structuré devrait inclure au minimum :
- timestamp : Instant exact au format ISO 8601 avec fuseau horaire UTC.
- level : Sévérité de l’événement (DEBUG, INFO, WARN, ERROR, FATAL).
- service : Nom du service qui émet le log.
- traceId / correlationId : Identifiant permettant de corréler les logs entre services.
- message : Description lisible de l’événement.
Niveaux de log
Les niveaux de log permettent de filtrer par sévérité et de maîtriser le volume d’information :
| Niveau | Utilisation | Exemple |
|---|---|---|
| DEBUG | Détail interne pour le développement | ”Requête exécutée en 12ms” |
| INFO | Événements normaux du métier | ”Commande ORD-789 créée” |
| WARN | Situations anormales non critiques | ”Retry n°2 vers le service de paiement” |
| ERROR | Défaillances nécessitant une attention | ”Timeout lors de la connexion à la DB” |
| FATAL | Le service ne peut pas continuer | ”Impossible d’initialiser le pool de connexions” |
Bonnes pratiques avec les niveaux
- Utilisez INFO pour les événements métier significatifs, pas pour chaque ligne de code.
- Réservez ERROR aux situations qui nécessitent réellement une intervention humaine.
- Configurez les niveaux de manière dynamique par service — pouvoir passer en DEBUG en production sans redéploiement est inestimable.
- Évitez de logger des données sensibles (mots de passe, tokens, PII) à quelque niveau que ce soit.
Centralisation des logs
Le problème des logs distribués
Lorsque vous avez 20 microservices tournant sur de multiples instances, les logs sont dispersés dans des dizaines de conteneurs. Sans centralisation, diagnostiquer un problème implique de se connecter manuellement à chaque instance.
Stack de centralisation
Le pattern le plus courant est la stack ELK (Elasticsearch, Logstash, Kibana) ou sa variante EFK (Elasticsearch, Fluentd, Kibana) :
- Collecte : Chaque service écrit ses logs sur stdout/stderr. Un agent (Fluentd, Filebeat, Fluent Bit) les collecte.
- Traitement : Les logs sont parsés, enrichis et transformés avant d’être stockés.
- Stockage : Elasticsearch indexe les logs pour une recherche rapide.
- Visualisation : Kibana permet de rechercher, filtrer et créer des dashboards sur les logs.
Alternatives modernes
- Loki (Grafana) : Stocke les logs en indexant uniquement les étiquettes, pas le contenu complet. Plus économique qu’Elasticsearch pour de gros volumes.
- CloudWatch Logs (AWS) : Solution managée pour les environnements AWS.
- Datadog Logs : Plateforme SaaS avec corrélation automatique entre logs, métriques et traces.
Bonnes pratiques
Du contexte, pas du bruit
Chaque ligne de log doit apporter un contexte utile. Posez-vous la question : « Si une alerte me réveille à 3 h du matin, ce log m’aide-t-il à comprendre ce qui s’est passé ? »
Correlation IDs
Propagez un traceId ou un correlationId dans chaque requête qui traverse plusieurs services. Cela permet de reconstituer le flux complet d’une opération en filtrant sur un seul ID.
Sampling en production
Pour les services à fort trafic, logger chaque requête peut coûter cher. Mettez en place du sampling : loggez 100 % des erreurs mais seulement un pourcentage des requêtes réussies.
Rétention et rotation
Définissez des politiques de rétention claires :
- Logs ERROR/FATAL : 90 jours minimum.
- Logs INFO : 30 jours.
- Logs DEBUG : Uniquement dans les environnements de développement ou activés temporairement.
Ne pas logger de données sensibles
N’incluez jamais dans les logs : mots de passe, tokens d’accès, numéros de carte, données personnelles identifiables (PII). Utilisez du masking ou une rédaction automatique si nécessaire.
Le logging en pratique
Pattern : middleware de request logging
Un middleware qui logge automatiquement chaque requête entrante et sa réponse :
→ REQUEST | method=POST path=/api/orders traceId=abc123 userId=USR-456
← RESPONSE | method=POST path=/api/orders traceId=abc123 status=201 duration=145ms
Pattern : error logging avec contexte
Lorsqu’une erreur survient, incluez tout le contexte nécessaire pour la diagnostiquer sans avoir à la reproduire :
ERROR | service=payment-service traceId=abc123 orderId=ORD-789
message="Pago rechazado por el proveedor"
provider=stripe errorCode=card_declined
retryCount=0 userId=USR-456
Résumé
Le logging structuré est le premier pilier de l’observabilité. Des logs bien formatés, centralisés et dotés d’un contexte adéquat permettent de diagnostiquer rapidement les problèmes, de comprendre le comportement du système et de répondre aux exigences d’audit. L’investissement dans une bonne stratégie de logging est largement rentabilisé dès la première fois que vous devez enquêter sur un incident en production.