Gcm4 journalise avec loguru. La
configuration est centralisée dans logging_config.py (issue #169) : c'est
le seul endroit qui pose les sorties (logger.add), en dehors du main()
des outils autonomes (issue #170).
| Niveau | Quand |
|---|---|
TRACE |
détail très fin, sur demande uniquement |
DEBUG |
entrée et sortie des fonctions (consigne « 2 debug() par fonction »), valeurs résumées |
INFO |
événements normaux : démarrage, connexion ouverte, import terminé (niveau par défaut) |
WARNING |
situation anormale dont l'application se remet : journal inaccessible, niveau inconnu, plugin ignoré |
ERROR |
échec d'une opération demandée par l'utilisateur ; logger.exception ajoute la pile |
Par ordre de priorité :
GCM_LOG_LEVEL=TRACE|DEBUG|INFO|WARNING|ERRORfixe le niveau. Un niveau inconnu retombe surINFOavec un avertissement.--debugsur la ligne de commande, ouGCM_DEBUG=1(true,yes,ouietonsont aussi acceptés) : niveauDEBUG.- Sans rien :
INFO.
./gnome_connection_manager.py --debug
GCM_LOG_LEVEL=TRACE ./gnome_connection_manager.py --config ~/test-gcm
GCM_DEBUG=1 GCM_LOG_FILE=/tmp/gcm-debug.log ./gnome_connection_manager.py--debug est retiré des arguments avant --config et avant la lecture des
hôtes passés en argument : il n'est jamais pris pour un nom d'hôte.
En mode debug, chaque ligne indique aussi le processus et le thread
émetteurs (les connexions et la vérification des mises à jour tournent dans
des threads), et logger.exception affiche la pile avec la valeur des
variables (backtrace et diagnose de loguru).
| Sortie | Contenu | Rotation |
|---|---|---|
| stderr | tout, au niveau demandé, en couleur dans un terminal | — |
<dossier de configuration>/log/gcm-app.log |
journal permanent de l'application (dossier par défaut ~/.gcm, ou celui de --config) |
10 Mo, conservé 14 jours |
GCM_LOG_FILE=chemin |
copie supplémentaire, par exemple pour joindre à un ticket | 10 Mo, 5 fichiers |
Si un fichier ne peut pas être ouvert (droits, disque plein), un avertissement est émis et l'application démarre quand même : stderr reste disponible.
À ne pas confondre avec l'enregistrement des sessions de terminal
(option « Journaliser » d'un hôte, case de journalisation continue) : ces
fichiers contiennent la sortie des terminaux, pas les traces de
l'application, et sont rangés dans <dossier de configuration>/logs/ et
<dossier de configuration>/log/ sous le nom de l'onglet.
- Les traces ne doivent contenir aucun secret : mots de passe d'hôte,
mots de passe VNC, URI SPICE, fichiers
.vvProxmox, clés privées, jetons d'API. Pour tracer une valeur, passer parlogging_config.summarize(valeur, nom): un nom qui évoque un secret (password,pwd,token,key,ticket...) est rendu***, les chaînes longues et les octets par leur taille, les identifiants d'URL masqués. - En mode debug, les piles d'exception affichent la valeur des variables
locales, qui peuvent contenir un mot de passe ou le contenu d'un
fichier. Relire un journal debug (et le fichier
GCM_LOG_FILE) avant de le joindre à un rapport de bug, et masquer ce qui doit l'être. - Les journaux des sessions de terminal enregistrent tout ce qui s'affiche, y compris un mot de passe saisi en clair dans une commande.
Détail dans CONSIGNES-AGENTS-IA.md §3.
from loguru import logger; jamaisimport logging, ni repli « si loguru est absent » (c'est une dépendance obligatoire). Vérifié partests/test_loguru_only.py.- Ne pas appeler
logger.addnilogger.removedans un module : seulslogging_config.pyet lemain()d'un outil autonome (tools/*.py,plugins/ssh/core.py,scripts/pr_coverage_comment.py,scripts/i18n_report.py,scripts/audit_debug_sorties.py,scripts/generate_class_diagram.py,scripts/check_branch_protection.py) configurent les sorties. Vérifié par le même test. - Au moins deux
debug()par fonction : à l'entrée et à chaque sortie.scripts/audit_debug_sorties.pyliste les fonctions qui ne le font pas encore (--details) ; leur total ne doit pas dépasserscripts/audit_debug_sorties.baseline(le baisser après avoir instrumenté du code). - Placeholders
{}de loguru (logger.info("hôte {} ouvert", nom)) ou f-string ; autant de{}que d'arguments, jamais%s, que loguru n'interprète pas. - Chaque
exceptjournalise (logger.exceptionoulogger.warningavec la cause) ; unexceptmuet cache une panne. Les manques hérités sont comptés fichier par fichier et ce compte ne peut que diminuer. - Tout module qui définit des fonctions a un logger de module
(
from loguru import logger). - Aucune variable de secret (
pwd,password,passphrase,key,token...) interpolée telle quelle : journaliserbool(password),len(pwd)oulogging_config.summarize(valeur, nom).
Ces règles sont vérifiées par tests/test_loguru_regles.py (analyse AST de
tout le dépôt, issue #171) et tests/test_secrets_journal.py, dans le job
Qualité.
- Les messages de journal ne sont pas traduits : ils s'adressent aux
développeurs et doivent rester identiques d'une langue à l'autre. Seuls
les textes affichés à l'utilisateur passent par
_().