Conception de logger : diagnostics et contrôle en production prioritaires
Dans les systèmes de production, les loggers ne sont pas évalués sur la vitesse de leur API, mais sur leur capacité à aider à diagnostiquer rapidement les incidents sans alourdir la charge. L'enregistrement de logs introduit un surcoût, minimisé en fonctionnement normal. Mais en cas de problème, des détails insuffisants ou des logs chaotiques rendent le dépannage impossible. Un bon logger garantit la diagnostiquabilité sans sacrifier les performances.
Le problème surgit quand la structure des logs reflète le code au lieu des processus métier. Dans les systèmes multithreadés, les messages de tâches différentes s'entremêlent, rendant difficile le suivi d'une requête spécifique.
Associer le contexte aux tâches
La solution consiste à associer les logs aux tâches, pas aux sites d'appel. Passer le contexte par paramètres alourdit les signatures de fonctions. Mieux vaut l'attacher au thread d'exécution.
Dans logme, cela se fait via des canaux de thread :
auto requestCh = Logme::Instance->CreateChannel(Logme::ID("req-42"));
LogmeThreadChannel(requestCh);
HandleRequest();
Le code interne logue automatiquement vers le canal :
void ParseHeaders() {
LogmeW("invalid header");
}
Les logs s'organisent désormais par opération. Dans spdlog et Quill, le contexte tourne autour du logger, plus simple mais moins adapté aux tâches.
Un autre souci est le bruit des messages répétés. Les erreurs de retry inondent les logs de doublons. Des limites au niveau événement résolvent cela :
LogmeW(LOGME_ONCE4THIS, "disque plein");
Le message n'apparaît qu'une fois par instance de classe, gardant les logs lisibles.
Routage flexible des messages
Une config globale ne suffit pas. Avec HTTP/2, il faut séparer logs de connexion et de requête. Un canal de requête se lie au canal protocole, mais les détails de requête ne doivent pas polluer le log principal.
Logme::Override ovr;
ovr.Add.DisableLink = true;
LogmeI(ovr, "détail spécifique à la requête");
Cela isole le message au canal local. Les événements généraux s'affichent partout ; les privés restent locaux.
Sous-systèmes pour un détail précis
Une dimension (canal) ne suffit pas. Les tâches ont des sous-systèmes : cache, réseau, parsing. Loguer sélectivement :
LOGME_SUBSYSTEM(cacheSid, "cache");
LOGME_SUBSYSTEM(parserSid, "parser");
LogmeD(cacheSid, "cache miss");
LogmeD(parserSid, "header analysé");
À l'exécution, activer seulement le sous-système nécessaire, comme le cache. Les autres restent muets, gardant les logs compacts.
Intégration avec les bibliothèques
Les bibliothèques tierces ont leur propre logging. On les intercepte et intègre :
void FfmpegLogCallback(void* ptr, int level, const char* fmt, va_list args) {
char buffer[2048];
vsnprintf(buffer, sizeof(buffer), fmt, args);
Logme::Override ovr;
ovr.Add.DisableLink = true;
LogmeW(ovr, "[ffmpeg] %s", buffer);
}
Les messages suivent les mêmes règles : canaux, sous-systèmes, déduplication.
Le support de formats facilite la migration :
LogmeI("value=%i", value);
fLogmeI("value={}", value);
LogmeI() << "value=" << value;
logme fusionne styles fmt et stream, contrairement à spdlog (fmt seul) et Quill (fmt asynchrone).
Contrôle en production sans redémarrage
Dans les systèmes toujours actifs, les logs restent minimaux en temps normal. Lors d'incidents :
- Soupçon sur le cache ? Activer son sous-système.
- Isoler la tâche via canal.
- Limiter les répétitions.
Le contrôle est dynamique via logmectl : niveaux, sous-systèmes, sans redémarrage.
Après correction, réduire les détails. Sinon, augmenter les logs globaux provoque une surcharge.
spdlog met l'accent sur la vitesse, Quill sur l'asynchronicité, logme sur le contrôle du flux de messages tout en préservant les performances.
Points clés :
- Les loggers doivent grouper par tâches via canaux, pas loggers.
- La déduplication au niveau événement réduit le bruit.
- Les sous-systèmes permettent un détail ciblé à l'exécution.
- L'intégration bibliothèques standardise la sortie.
- Le contrôle dynamique sans redémarrage est essentiel en production.
— Editorial Team
Aucun commentaire pour le moment.