Six mois de journaux OpenClaw. C’est ce que j’avais lorsque je me suis finalement assis pour comprendre pourquoi certaines sessions de débogage prenaient 5 minutes et d’autres 2 heures. La réponse était évidente rétrospectivement : journalisation.
Ce n’était pas une question de savoir si j’avais des journaux — j’en avais toujours. Le problème était que la moitié de mes journaux constituait un bruit inutile (« Process started… process running… process still running… ») et l’autre moitié manquait des informations dont j’avais réellement besoin lorsque les choses ne fonctionnaient pas.
Voici ce que j’ai changé, et comment mon temps de débogage est passé en moyenne de 45 minutes à environ 12 minutes par incident.
Le Problème Avec la Journalisation Par Défaut
La journalisation par défaut est conçue par des développeurs qui savent ce que tout signifie. Quand le développeur voit « Context compaction triggered at 142K chars, » il sait exactement ce que cela signifie et ce qu’il faut vérifier ensuite. Quand je le vois à 3 heures du matin, je me demande « est-ce normal ? 142K est-il élevé ? Était-il censé se compacter à 142K ou à 100K ? Cela a-t-il un rapport avec l’erreur que j’enquête ? »
Les journaux par défaut supposent que vous avez une connaissance parfaite du système. Le débogage en production se produit lorsque vous avez une connaissance imparfaite et que vous êtes probablement stressé.
Ce Que Je Journalise Maintenant
J’ai restructuré ma journalisation autour d’un principe : chaque entrée de journal doit m’aider à répondre à « que s’est-il passé et pourquoi ? » sans avoir besoin de regarder un autre système.
Appels API : Modèle utilisé, nombre de tokens d’entrée, nombre de tokens de sortie, temps de réponse, statut (succès/erreur), message d’erreur le cas échéant. Une ligne par appel. Cela me dit immédiatement si l’API est lente, échoue ou est coûteuse.
Exécutions d’outils : Nom de l’outil, résumé d’entrée, résumé de sortie, durée, succès/échec. Lorsque qu’un outil échoue, je peux voir exactement ce qui a été tenté et ce qui a mal tourné sans fouiller dans la sortie brute.
Activité de session : Démarrage de session, événements significatifs (message de nouvel utilisateur, appel d’outil, compaction de contexte), fin de session. Cela me donne une chronologie de ce qui s’est passé dans chaque session.
Erreurs : Message d’erreur complet, trace de la pile, contexte pertinent (ID de session, requête utilisateur, activité récente). Le contexte est crucial — une erreur sans contexte vous dit qu’un problème s’est produit, mais pas pourquoi.
Ce Que J’ai Arrêté de Journaliser : Battements de cœur de routine (« still alive » messages toutes les 30 secondes), vérifications de santé réussies, transitions d’état internes qui sont normales et attendues. Cela ajoutait du volume sans ajouter d’informations.
Niveaux de Journalisation Qui Ont Du Sens
La plupart des frameworks de journalisation offrent les niveaux DEBUG, INFO, WARN, ERROR. Je les utilise comme ceci :
ERROR : Quelque chose a échoué et nécessite une attention humaine. Je lis chaque journal ERROR. Si j’obtiens plus de 5 entrées ERROR par jour en fonctionnement normal, mes seuils sont incorrects.
WARN : Quelque chose d’inhabituel s’est produit mais le système l’a géré. Limite de taux atteinte et retardée, compaction de contexte déclenchée, la nouvelle tentative a réussi après un échec. Je passe en revue les entrées WARN quotidiennement pour repérer des modèles.
INFO : Opérations normales que je pourrais vouloir retracer. Appels API, exécutions d’outils, événements de session. Je ne lis cela que lorsque je débogue un problème spécifique.
DEBUG : État interne détaillé pour un débogage approfondi. Entrée/sortie de chaque fonction, allocation mémoire, état du pool de connexions. Désactivé en production à moins que j’enquête un bug spécifique.
La clé : en production, je fonctionne au niveau INFO. Cela me donne suffisamment de détails pour diagnostiquer la plupart des problèmes sans le bruit du DEBUG. Je passe temporairement au DEBUG lorsque j’examine des problèmes spécifiques, puis je reviens au niveau INFO.
Journalisation Structurée
Les journaux en texte brut sont difficiles à rechercher et impossibles à agréger. Je suis passé à une journalisation structurée en JSON :
Au lieu de : 2024-03-15 14:23:45 ERROR API call failed: timeout after 30s
Je journalise : un objet JSON avec horodatage, niveau, type d’événement, modèle, erreur, durée, ID de session et ID de requête.
Le format JSON me permet de :
– Rechercher par n’importe quel champ (toutes les erreurs pour la session X, tous les délais pour le modèle Y)
– Agréger des métriques (temps de réponse moyen par modèle par heure)
– Construire des tableaux de bord (Grafana peut lire directement les journaux JSON)
– Corréler des événements (suivre une requête depuis son arrivée jusqu’à sa réponse)
Le compromis : les journaux JSON sont moins lisibles pour l’homme lorsque vous surveillez le fichier journal. J’utilise un outil de visualisation de journaux qui formate joliment le JSON pour une surveillance en temps réel.
Rotation et Conservation des Journaux
Les journaux des agents AI croissent rapidement. Une instance OpenClaw modérément active génère 50 à 200 Mo de journaux par jour au niveau INFO. Sans rotation, votre disque sera plein en quelques semaines.
Ma politique de conservation :
– Derniers 7 jours : journaux complets (niveau INFO), non compressés pour un accès rapide
– Jours 8-30 : journaux compressés (gzipped, environ 10x de réduction de taille)
– Jours 31-90 : entrées ERROR et WARN uniquement (extraction des journaux complets avant suppression)
– Au-delà de 90 jours : uniquement des métriques agrégées mensuelles (pas de journaux bruts)
Cela garde mon stockage total de journaux en dessous de 5 Go tout en maintenant suffisamment d’historique pour l’analyse des tendances et l’enquête sur les incidents.
Le Flux de Travail de Débogage
Lorsque quelque chose ne fonctionne pas, je suis cette séquence :
1. Vérifiez les 10 dernières entrées ERROR — cela révèle généralement la cause immédiate
2. Recherchez le même type d’erreur dans la semaine passée — s’agit-il d’un problème récurrent ou d’un cas isolé ?
3. Regardez la chronologie autour de l’erreur — que s’est-il passé dans les 60 secondes avant l’erreur ?
4. Vérifiez les événements corrélés — l’erreur a-t-elle coïncidé avec un déploiement, un changement de configuration ou une panne de service externe ?
Cette approche systématique, combinée à une bonne journalisation, résout la plupart des problèmes en 10 à 15 minutes. Avant la journalisation structurée, les mêmes problèmes prenaient 30 à 60 minutes car les étapes 3 et 4 nécessitaient des fouilles manuelles dans le fichier journal.
🕒 Published: