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 :

NiveauUtilisationExemple
DEBUGDé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”
WARNSituations anormales non critiques”Retry n°2 vers le service de paiement”
ERRORDéfaillances nécessitant une attention”Timeout lors de la connexion à la DB”
FATALLe 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) :

  1. Collecte : Chaque service écrit ses logs sur stdout/stderr. Un agent (Fluentd, Filebeat, Fluent Bit) les collecte.
  2. Traitement : Les logs sont parsés, enrichis et transformés avant d’être stockés.
  3. Stockage : Elasticsearch indexe les logs pour une recherche rapide.
  4. 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.