# Documentation Django 6.0.7

# Configuration et utilisation de la journalisation

Voir aussi

- Référence de la journalisation dans Django

- Aperçu de la journalisation dans Django

Django contient une configuration de journalisation par défaut fonctionnelle qui peut facilement être étendue.

## Appel de journalisation basique

Pour envoyer un message de journalisation à partir de votre code, écrivez un appel de journalisation.

Ne soyez pas tenté-e-s d’utiliser des appels de journalisation dans `settings.py`.

La façon dont la journalisation de Django est configuré dans le cadre de la fonction `setup()` signifie que les appels de journalisation placés dans `settings.py` peuvent ne pas fonctionner comme prévu, car la journalisation n’est pas encore configurée à ce stade. Pour explorer la journalisation, utilisez une fonction de vue comme suggéré dans l’exemple ci-dessous.

Tout d’abord, importez la bibliothèque Python `logging` et obtenez une instance de journalisation avec `logging.getLogger()`. Passez à la méthode `getLogger()` un nom pour l’identifier et pour les lignes qu’il produira. Une bonne option est d’utiliser `__name__` (voir Utilisation de l’espace de noms des journaliseurs ci-dessous pour en savoir plus), ce qui donnera le nom du module Python actuel sous forme de chemin pointé

    import logging

    logger = logging.getLogger(__name__)

Par convention, il est bon d’effectuer cette déclaration au niveau du module.

Puis dans une fonction, par exemple dans une vue, envoyez un enregistrement au journaliseur

    def some_view(request):
        ...
        if some_risky_state:
            logger.warning("Platform is running at risk")

Lorsque ce code est exécuté, un objet `LogRecord` contenant ce message sera envoyé au journaliseur. SI vous utilisez la configuration de journalisation de Django par défaut, le message apparaîtra dans la console.

Le niveau `WARNING` utilisé dans l’exemple ci-dessus est l’un des quelques niveaux de sévérité de journalisation: DEBUG`, `INFO`, `WARNING`, `ERROR`, `CRITICAL`. Un autre exemple pourrait être

    logger.critical("Payment system is not responding")

Important

Les enregistrements ayant un niveau plus faible que `WARNING` n’apparaîtront pas dans la console par défaut. La modification de ce comportement nécessite une configuration supplémentaire.

## Personnalisation de la configuration de journalisation

Même si la configuration de journalisation de Django fonctionne telle quelle, vous pouvez contrôler exactement la manière dont vos journaux sont envoyés à diverses destinations, vers des fichiers journaux, des services externes, par courriel, etc. en ajoutant un peu de configuration supplémentaire.

Vous pouvez configurer :

- les correspondances des journaliseurs (logger) pour déterminer quels enregistrements sont envoyés à quels gestionnaires

- les gestionnaires (handler) pour déterminer ce qu’ils font des enregistrements qu’ils reçoivent

- les filtres, pour ajouter du contrôle supplémentaire sur le transfert des enregistrements, et même les modifier sur place

- les formateurs, pour convertir les objets `LogRecord` en une chaîne ou toute autre forme qui soit lisible par les humains ou un autre système

Il existe plusieurs manières de configurer la journalisation. Dans Django, le réglage `LOGGING` est le plus couramment utilisé. Ce réglage utilise le format dictConfig, et étend la configuration de journalisation par défaut.

Consultez Configuration de la journalisation pour une explication sur la manière dont vos réglages personnalisés sont fusionnés avec ceux de Django.

Consultez la `documentation de journalisation de Python` pour plus de détails sur les autres manières de configurer la journalisation. Par simplification, cette documentation ne va considérer que la configuration au travers du réglage `LOGGING`.

### Configuration de journalisation basique

Lors de la configuration de la journalisation, il est raisonnable de

#### Créer un dictionnaire `LOGGING`

Dans votre fichier `settings.py`:

    LOGGING = {
        "version": 1,  # the dictConfig format version
        "disable_existing_loggers": False,  # retain the default loggers
    }

Il est presque toujours recommandé de conserver et étendre la configuration de journalisation par défaut en définissant `disable_existing_loggers` à `False`.

#### Configurer un gestionnaire

Cet exemple configure un seul gestionnaire (handler) nommé `file`, qui utilise la classe `FileHandler` de Python pour enregistrer les journaux de niveau `DEBUG` et plus élevé dans le fichier `general.log` (à la racine du projet) :

    LOGGING = {
        # ...
        "handlers": {
            "file": {
                "class": "logging.FileHandler",
                "filename": "general.log",
            },
        },
    }

Différentes classes de gestionnaire acceptent différentes options de configuration. Pour plus d’informations sur les classes de gestionnaire disponibles, consultez `AdminEmailHandler` fournie par Django et les diverses `classes de gestionnaire` fournies par Python.

Les niveaux de journalisation peuvent aussi être définis sur les gestionnaires (par défaut, elles acceptent des messages de tous les niveaux). En utilisant l’exemple ci-dessus, l’ajout de :

    {
        "class": "logging.FileHandler",
        "filename": "general.log",
        "level": "DEBUG",
    }

définirait une configuration de gestionnaire n’acceptant que des enregistrements de niveau `DEBUG` ou supérieur.

#### Configuration d’une correspondance de journaliseur

Pour envoyer des enregistrements à ce gestionnaire, configurez une correspondance pour l’utiliser, par exemple :

    LOGGING = {
        # ...
        "loggers": {
            "": {
                "level": "DEBUG",
                "handlers": ["file"],
            },
        },
    }

Le nom de correspondance détermine quels sont les enregistrements de journaux qu’il va traiter. Cette configuration (`''`) is anonyme. Cela signifie qu’elle traitera les enregistrements de tous les journaliseurs (voir Utilisation de l’espace de noms des journaliseurs ci-dessous sur la manière d’utiliser les noms de correspondance pour déterminer les journaliseurs concernés par le traitement de ses enregistrements).

Ceci va transmettre les messages de niveau `DEBUG` et supérieur au gestionnaire nommé `file`.

Notez qu’un journaliseur peut transmettre des messages à plusieurs gestionnaires, il existe donc une relation de type plusieurs-à-plusieurs entre les journaliseurs et les gestionnaires.

Si vous exécutez

    logger.debug("Attempting to connect to API")

dans vote code, vous trouverez ce message dans le fichier general.log` à la racine de votre projet.

#### Configuration d’un formateur

By default, the final log output contains the message part of each `LogRecord` object. Use a formatter if you want to include additional data. First name and define your formatters - this example defines formatters named `verbose` and `simple`:

    LOGGING = {
        # ...
        "formatters": {
            "verbose": {
                "format": "{name} {levelname} {asctime} {module} {process:d} {thread:d} {message}",
                "style": "{",
            },
            "simple": {
                "format": "{levelname} {message}",
                "style": "{",
            },
        },
    }

Le mot-clé `style` permet d’indiquer `{` pour la mise en forme `str.format()` ou `$` pour `string.Template`; la valeur par défaut est `$`.

Voir LogRecord attributes au sujet des attributs de `LogRecord` qu’il est possible d’inclure.

Pour appliquer un formateur à un gestionnaire, ajoutez une entrée `formatter` au dictionnaire du gestionnaire en vous référant au formateur par son nom, par exemple :

    "handlers": {
        "file": {
            "class": "logging.FileHandler",
            "filename": "general.log",
            "formatter": "verbose",
        },
    }

#### Utilisation de l’espace de noms des journaliseurs

La configuration de journalisation anonyme `''` capture les journaux de n’importe quelle application Python. Une configuration de journalisation nommée ne capturera que les journaux de journaliseurs dont le nom correspond.

L’espace de noms d’une instance de journaliseur est défini en utilisant `getLogger()`. Par exemple, dans `views.py` de `my_app`:

    logger = logging.getLogger(__name__)

va créer un journaliseur dans l’espace de noms `my_app.views`. `__name__` permet d’organiser automatiquement les messages de journalisation en fonction de leur provenance dans les applications de votre projet. Cela garantit par la même occasion que les collisions de noms seront évitées.

Une correspondance de journaliseur nommée `my_app.views` va capturer les enregistrements de ce journaliseur :

    LOGGING = {
        # ...
        "loggers": {
            "my_app.views": {...},
        },
    }

Une correspondance de journaliseur nommée `my_app` sera plus permissive, capturant les enregistrements de journaliseurs partout dans l’espace de noms `my_app` (y compris my_app.views`, `my_app.utils` et ainsi de suite) :

    LOGGING = {
        # ...
        "loggers": {
            "my_app": {...},
        },
    }

Il est aussi possible de définir les espaces de noms des journaliseurs de manière explicite

    logger = logging.getLogger("project.payment")

et de définir ensuite en fonction les correspondances de journaliseurs.

##### Utilisation des hiérarchies et de la propagation des journaliseurs

La nomenclature des journaliseurs est hiérarchique. `my_app` est le parent de `my_app.views`, qui est le parent de `my_app.views.private`. Sans autre indication, les correspondances de journaliseurs vont propager les enregistrements qu’elles traitent à leurs parents ; un enregistrement d’un journaliseur dans l’espace de noms `my_app.views.private` sera traité à la fois par les correspondances de `my_app` et de `my_app.views`.

Pour contrôler ce comportement, donnez une valeur à la clé de propagation sur les correspondances que vous définissez

    LOGGING = {
        # ...
        "loggers": {
            "my_app": {
                # ...
            },
            "my_app.views": {
                # ...
            },
            "my_app.views.private": {
                # ...
                "propagate": False,
            },
        },
    }

`propagate` vaut `True` par défaut. Dans cet exemple, les journaux de `my_app.views.private` ne seront pas traités par les parents, mais les journaux de `my_app.views` le seront.

### Configuration de journalisation réactive

La journalisation est d’autant plus utile qu’elle contient des informations riches, mais sans information inutile, et cette pesée d’intérêts dépend de ce que vous faites. Lorsque vous êtes en mode débogage, le niveau d’informations souhaité dépasse largement ce qui sera nécessaire lorsque vous passerez votre projet en production.

Vous pouvez configurer la journalisation pour qu’elle vous offre le niveau de détail nécessaire au moment où vous en avez besoin. Au lieu de modifier manuellement la configuration pour cet objectif, une meilleure façon est d’appliquer une configuration automatiquement en fonction de l’environnement.

Par exemple, vous pouvez définir une variable d’environnement `DJANGO_LOG_LEVEL` appropriée dans vos environnements de développement et de pré-production, et en faire usage dans une configuration de journaliseur de cette façon

    "level": os.getenv("DJANGO_LOG_LEVEL", "WARNING")

de cette manière, tant que l’environnement n’indique par un niveau de journalisation plus bas, cette configuration ne propagera que les enregistrements de sévérité `WARNING` et supérieure à son gestionnaire.

D’autres options de la configuration (comme les options `level` ou `formatter` des gestionnaires) peuvent également être ajustées de cette façon.