Le module logging est l'outil standard de Python pour la journalisation. Il met en œuvre une hiérarchie de loggers et prend en charge les niveaux de journalisation (severity levels) : DEBUG, INFO, WARNING, ERROR, CRITICAL. Une utilisation correcte permet de gérer centralement la sortie, de sauvegarder les logs dans des fichiers, de les envoyer par email, de filtrer par niveau, etc.
L'idée principale est de créer des loggers avec des noms (logging.getLogger(__name__)) dans chaque module, sans créer de logger racine global à partir de zéro dans chaque endroit. La configuration (format, gestionnaires, niveau) se fait de manière centralisée au démarrage de l'application.
Exemple de configuration :
import logging logging.basicConfig(format='%(levelname)s:%(name)s:%(message)s', level=logging.INFO) logger = logging.getLogger(__name__) def foo(): logger.info('Message informatif') logger.error('Erreur !') foo()
Pourquoi ne peut-on pas appeler logging.basicConfig() dans chaque module ? Que se passera-t-il si l'on fait cela ?
Réponse : logging.basicConfig() configure le logger racine une seule fois par session Python. Les appels répétés, si le logger racine a déjà été initialisé, seront ignorés. En conséquence, si différents modules essaient d'appeler basicConfig() avec leurs propres formats/niveaux, seul le premier prendra effet !
Histoire
Dans un grand projet, chaque développeur configurait la journalisation à sa manière via basicConfig et des gestionnaires locaux. À cause de cela, certains logs n'étaient pas du tout affichés, d'autres étaient dupliqués 10 fois, et les messages de différents modules ne tenaient pas dans un seul fichier.
Histoire
Lors de la migration d'un service web vers une journalisation multi-niveaux, on a oublié de spécifier le nom du logger via getLogger(__name__), on écrivait partout dans le logger racine. En conséquence, il était impossible de savoir d'où provenait un log spécifique.
Histoire
On utilisait la fonction logger.error() pour enregistrer tous les messages, même ceux qui n'étaient pas des erreurs. En conséquence, les systèmes de surveillance automatiques déclenchaient constamment des alertes, car ils voyaient un niveau élevé d'erreurs, alors qu'il s'agissait simplement de messages de debug/informationnels.