Tout développeur Python connaît la scène : ton script plante en production, et tu parsèmes des print() un peu partout pour comprendre ce qui s'est passé. Tu relances, tu inspectes la sortie, tu retires les print(), tu en oublies un, tu recommences. C'est long, c'est sale, et surtout ça ne te dit pas quand le problème est survenu.
Le logging est la version adulte du débogage : des messages horodatés, classés par niveau de gravité, écrits dans un fichier que tu peux relire après coup, sans jamais polluer ton code métier. Le souci, c'est que le module logging de la bibliothèque standard te force à écrire vingt lignes de configuration avant d'afficher le moindre message. loguru règle ça d'un coup : une ligne, et tes logs sont propres, colorés, dans un fichier, avec la date, le niveau et le fichier source. On y va.
Dans ce tutoriel, tu vas remplacer tes print() par un vrai système de logs : installer loguru, écrire dans un fichier avec rotation, capturer les exceptions automatiquement, attacher du contexte à tes messages et envoyer du JSON propre à tes outils d'analyse. Aucune configuration à rallonge, promis.
Installe loguru
Une seule commande suffit :
pip install loguruPas de dépendance exotique, pas d'étape de compilation. loguru s'installe en une seconde sur Python 3.7 et plus, et fonctionne partout où Python tourne, que ce soit sur ton poste, un serveur ou un conteneur Docker.
Tes premiers logs en une ligne
Oublie les handlers, les formatters et les autres cauchemars de logging. Avec loguru, tu importes un logger déjà prêt à l'emploi :
from loguru import logger
logger.info("Le script démarre")
logger.warning("Attention, cette valeur est vide")
logger.error("Impossible de se connecter à l'API")Dès la première exécution, tu obtiens des messages colorés dans le terminal, chacun précédé de l'heure exacte, du niveau (INFO, WARNING, ERROR) et du fichier plus la ligne d'où il provient. Tu sais d'un coup d'œil où et quand chaque événement s'est produit, sans écrire la moindre configuration. Les niveaux te servent de filtre : INFO pour le déroulement normal, WARNING pour ce qui mérite ton attention, ERROR pour ce qui casse. Avec le module standard, il te faudrait un logger, un handler, un formatter et un basicConfig avant d'en voir la moindre ligne.
Écrire dans un fichier, avec rotation automatique
Le terminal, c'est parfait pour développer. En production, tu veux un fichier que tu peux consulter après coup. Avec loguru, une ligne suffit :
logger.remove() # on retire le handler par défaut
logger.add("app.log", rotation="1 MB", retention="7 days", level="DEBUG")
logger.debug("Message de debug écrit dans app.log")
logger.info("Traitement terminé")Deux options font tout le travail. rotation="1 MB" crée automatiquement un nouveau fichier dès que app.log dépasse un mégaoctet, et retention="7 days" supprime les vieux logs au bout d'une semaine. Fini les fichiers de 40 Go qui remplissent ton disque en silence pendant que tu dors. Ajoute compression="zip" si tu veux que chaque rotation soit archivée en .gz et que ton dossier de logs reste minuscule.
Capturer les exceptions sans try/except
Le réflexe try/except pour journaliser une erreur est verbeux, et surtout facile à oublier. loguru propose un décorateur qui fait le travail à ta place :
from loguru import logger
@logger.catch
def diviser(a, b):
return a / b
diviser(10, 0)Décore une fonction avec @logger.catch, et toute exception qui en sort sera automatiquement capturée, journalisée avec sa trace complète, puis relancée. Ton programme garde son comportement normal, mais tu obtiens enfin la trace d'erreur dans tes logs au lieu d'un crash muet. Le décorateur accepte des options pour exclure certaines exceptions ou gérer le résultat, mais la version nue couvre déjà la grande majorité des besoins.
Ajouter du contexte à tes logs
Quand ton script traite des milliers d'utilisateurs, un log qui dit « échec » sans dire pour qui ne sert à rien. logger.bind() attache des variables à un message précis :
for user_id in [1, 2, 3]:
logger.bind(user_id=user_id).info("Traitement de l'utilisateur")Chaque ligne de log contient désormais user_id=1, user_id=2, et ainsi de suite. Plus besoin de concaténer des f-strings dans tous les sens pour retrouver ton coupable dans un flot de messages identiques. Tu peux aussi combiner bind avec le nom d'un job ou d'un environnement pour tracer toute une campagne de traitements d'un seul regard.
Passer en JSON pour les machines
Si tes logs finissent dans un outil d'analyse comme Grafana, Datadog ou une base de données, tu veux du JSON plutôt que du texte libre :
import sys
from loguru import logger
logger.remove()
logger.add(sys.stdout, serialize=True)
logger.info("Ce log est du JSON")Avec serialize=True, chaque message devient un objet JSON complet : le niveau, l'horodatage, le fichier, la ligne, le message, l'identifiant du processus et du thread. Des outils comme Grafana Loki ou Datadog ingèrent ce format directement : tu peux alors rechercher, filtrer et alerter sur tes logs comme sur n'importe quelle donnée structurée.
Ne pas ralentir ton script : les logs asynchrones
Si ton script écrit des milliers de lignes par seconde, l'écriture sur disque peut devenir un goulot d'étranglement. Ajoute enqueue=True et loguru place les écritures dans une file d'attente traitée en arrière-plan :
logger.add("app.log", rotation="10 MB", enqueue=True)Ton programme n'attend plus que chaque ligne soit physiquement écrite avant de continuer. C'est le réflexe à adopter dès que tu journalises dans une boucle serrée ou un traitement massif de données.
Conclusion
loguru ne réinvente pas le logging, il le rend supportable. Une ligne pour démarrer, une ligne pour un fichier avec rotation, un décorateur pour les exceptions, et du contexte ou du JSON quand tu en as besoin. La prochaine fois que ton script fera des siennes, tu sauras exactement ce qui s'est passé, où et quand.
Et si tu veux creuser, la documentation de loguru couvre des sujets avancés comme les couleurs personnalisées, les sinks asynchrones ou la compression des vieux logs en .gz.






