Qu'est-ce que le logging en Python ?

Qu'est-ce que le logging en Python ?

Le module logging fait partie de la bibliothèque standard et permet de capturer des événements dans notre application. Plus flexible que les print, il permet de savoir ce qui se passe dans notre code, du simple message d'information à l'erreur critique.

Quelle différence entre print et logging ?

On a souvent tendance à utiliser print pour du débogage (je suis le premier coupable).
Pour quelque chose de simple ou un débogage rapide, un print temporaire peut suffire.
Cependant, le module logging est la solution adaptée pour surveiller vos applications.

  • print permet d’afficher des informations uniquement dans la console, alors que logging peut les envoyer vers la console, un fichier, un serveur distant ou même par e-mail

  • print ne permet pas de distinguer des niveaux d'importance, alors que logging définit différents seuils de criticité (DEBUG, INFO, WARNING, ERROR, CRITICAL)

  • logging enregistre automatiquement des métadonnées comme l’heure de l’événement, le fichier ou la ligne concernée

  • Les appels à print doivent être supprimés manuellement pour cesser l'affichage, tandis que logging peut être désactivé via une configuration, sans modifier le code

Comment fonctionne un logger Python ?

Nous allons voir comment implémenter le logging, étape par étape, d'une utilisation basique à une utilisation un peu plus avancée. Bien que nous revenions plus tard sur ce concept, il faut savoir qu'il existe six niveaux de gravité : NOTSET, DEBUG, INFO, WARNING, ERROR, CRITICAL.

Par défaut, Python ne logue qu'à partir du niveau WARNING :

import logging

logging.debug("Ceci ne s'affichera pas")
logging.info("Ceci non plus")
logging.warning("Ceci s'affichera")
logging.error("Ceci aussi")
PYTHON

Mettre en place son premier logging

Ici, nous allons simplement apprendre à nous passer du print. Commençons par importer le module logging et utilisons basicConfig pour dire au logger : « Affiche tout ce qui est au moins aussi important que le niveau INFO ». Enfin, nous utilisons logging.info à la place de print.

import logging


# Configuration minimale : on règle le seuil de déclenchement sur INFO
logging.basicConfig(level=logging.INFO)

def envoyer_email(destinataire, sujet):
    logging.info(f"Préparation de l'email pour {destinataire}")

    # ... code d'envoi fictif ...

    logging.info(f"Email '{sujet}' envoyé avec succès !")


envoyer_email("[email protected]", "Votre facture est disponible")

# Résultat :
# INFO:root:Préparation de l'email pour [email protected]
# INFO:root:Email 'Votre facture est disponible' envoyé avec succès !
PYTHON

INFO est le niveau, root le nom du logger par défaut et le reste est votre message.

Enregistrer dans un fichier

Dans notre exemple précédent, le problème est que, lorsque l'on ferme la console, nos logs disparaissent avec elle. Nous allons voir comment écrire dans un fichier. Par exemple, pour des applications en production, vous conserverez vos logs dans un fichier afin de pouvoir consulter les éventuelles erreurs.

Nous utilisons le paramètre filename pour que Python puisse créer un fichier et écrire dedans, ainsi que le paramètre format pour l'affichage des logs.

import logging

logging.basicConfig(
    filename='robot_aspirateur.log', # Le fichier sera créé automatiquement
    level=logging.WARNING,           # On ne veut que les problèmes (WARNING et plus)
    format='%(asctime)s - %(levelname)s - %(message)s', 
    filemode='a'                     # 'a' pour Append (ajouter à la fin)
)

# Simulation d'événements
logging.warning("Batterie faible (15%) - Retour à la base demandé")
logging.error("Roue gauche bloquée : Chaussette détectée !")
PYTHON

Et dans le fichier de logs :

2026-01-26 09:26:42,618 - WARNING - Batterie faible (15%) - Retour à la base demandé
2026-01-26 09:26:42,619 - ERROR - Roue gauche bloquée : Chaussette détectée !
BASH

À noter

%(asctime)s, %(levelname)s et %(message)s agissent comme des balises : Python les remplacera automatiquement par l'heure exacte, le niveau de gravité et le contenu de votre message au moment de l'écriture.

Le logging dans un projet multimodule

Imaginons maintenant une application, Django par exemple, comprenant plusieurs fichiers. Les logs peuvent provenir de sources diverses et être écrits dans un seul fichier, mais nous voulons savoir de quel module provient l'anomalie.

Prenons un exemple de gestion des ressources humaines avec deux fichiers (oui, nous sommes minimalistes ici 😅) :

  • Dans le fichier principal main.py, on configure le logging une seule fois (root) et sa configuration s'applique à tout le projet

  • Dans le module gestion_rh.py, on ne configure rien, on récupère juste un logger portant le nom du module via getLogger(__name__)

# main.py
import logging
import gestion_rh  # Notre module de gestion des employés

# 1. Configuration unique du "Root Logger"
logging.basicConfig(
    filename='paie.log',
    level=logging.INFO,
    format='%(asctime)s - %(name)s - %(levelname)s - %(message)s',
    datefmt='%H:%M:%S',
    filemode='w'  # Pour écraser le fichier à chaque exécution
)

# 2. Logger pour le script principal
logger = logging.getLogger(__name__) 
logger.info("Lancement du logiciel de paie v2.0")

# 3. Traitement des employés via le module externe
gestion_rh.verser_salaire("Sophie")
gestion_rh.verser_salaire("Patrick") # Le cas délicat...
PYTHON
#gestion_rh.py
import logging

# Ici, PAS de basicConfig. 
# On crée juste une instance de logger nommée 'gestion_rh' (grâce à __name__)
logger = logging.getLogger(__name__) 

def verser_salaire(employe):
    logger.info(f"Traitement du dossier : {employe}")
    try:
        if employe == "Patrick":
            # Simulation d'une règle métier stricte
            raise ValueError("Erreur : Trop de pauses café, virement bloqué.")

        logger.info(f"Virement effectué avec succès pour {employe}.")

    except Exception:
        # L'argument exc_info=True ajoute la trace complète de l'erreur dans le log
        logger.error(f"Échec du virement pour {employe}", exc_info=True)
PYTHON

Sortie dans le fichier de log :

09:46:27 - __main__ - INFO - Lancement du logiciel de paie v2.0
09:46:27 - gestion_rh - INFO - Traitement du dossier : Sophie
09:46:27 - gestion_rh - INFO - Virement effectué avec succès pour Sophie.
09:46:27 - gestion_rh - INFO - Traitement du dossier : Patrick
09:46:27 - gestion_rh - ERROR - Échec du virement pour Patrick
Traceback (most recent call last):
  File "/Users/gabrieltrouve/Pro/sandbox/gestion_rh.py", line 12, in verser_salaire
    raise ValueError("Erreur : Trop de pauses café, virement bloqué.")
ValueError: Erreur : Trop de pauses café, virement bloqué.
BASH

On voit bien ici de quel fichier proviennent les différents logs.

Les niveaux de log

Nom Niveau Quand utiliser
DEBUG 10 Informations détaillées pour diagnostiquer des problèmes, utile pendant le développement
INFO 20 Confirmation que les choses fonctionnent comme prévu, messages informatifs généraux
WARNING 30 Indication qu'un événement inattendu s'est produit ou pourrait se produire, mais l'application fonctionne encore
ERROR 40 Un problème sérieux s'est produit, une fonctionnalité n'a pas pu s'exécuter
CRITICAL 50 Erreur grave qui pourrait empêcher l'application de continuer à fonctionner

À noter

  • Quand un logger a le niveau NOTSET, il délègue au logger parent

  • Si le logger racine (root) a NOTSET, il utilise WARNING par défaut

Le logger fonctionne en comparant le niveau du message avec le niveau configuré. La règle est simple : si le niveau du message est supérieur ou égal au niveau configuré, alors le message est affiché.

Bravo, tu es prêt à passer à la suite

Rechercher sur le site

Formulaire de contact

Inscris-toi à Docstring

Pour commencer ton apprentissage.

Tu as déjà un compte ? Connecte-toi.