# Documentation Django 6.0.7

# Journalisation

Voir aussi

- Configuration et utilisation de la journalisation

- Aperçu de la journalisation dans Django

Le module de journalisation de Django étend le module Python intégré `logging`.

La journalisation est configurée dans le contexte plus général de la fonction `django.setup()` de Django, ce qui fait qu’elle est toujours disponible, sauf si elle est explicitement désactivée.

## Configuration de journalisation par défaut de Django

Par défaut, Django utilise le format logging.config.dictConfig de Python.

### Conditions de journalisation par défaut

Les conditions complètes de journalisation par défaut sont :

Lorsque `DEBUG` vaut `True`:

- Le journaliseur `django` envoie les messages de la hiérarchie `django` (sauf `django.server`) de niveau `INFO` ou plus vers la console.

Lorsque `DEBUG` vaut `False`:

- Le journaliseur `django` envoie les messages de la hiérarchie `django` (sauf `django.server`) de niveau `ERROR` ou `CRITICAL` à `AdminEmailHandler`.

Indépendamment de la valeur de `DEBUG`:

- Le journaliseur django.server envoie des messages au niveau `INFO` et plus à la console.

Tous les journaliseurs à l’exception de django.server propagent la journalisation vers leur parent, jusqu’au journaliseur racine `django`. Les gestionnaires `console` et `mail_admins` sont liés au journaliseur racine pour offrir le comportement décrit ci-dessus.

Les valeurs par défaut de Python envoient les enregistrements de niveau `WARNING` et supérieur dans la console.

### Définition de journalisation par défaut

La configuration de journalisation par défaut de Django hérite des valeurs par défaut de Python. Elle est disponible dans `django.utils.log.DEFAULT_LOGGING` et définie dans django/utils/log.py:

    {
        "version": 1,
        "disable_existing_loggers": False,
        "filters": {
            "require_debug_false": {
                "()": "django.utils.log.RequireDebugFalse",
            },
            "require_debug_true": {
                "()": "django.utils.log.RequireDebugTrue",
            },
        },
        "formatters": {
            "django.server": {
                "()": "django.utils.log.ServerFormatter",
                "format": "[{server_time}] {message}",
                "style": "{",
            }
        },
        "handlers": {
            "console": {
                "level": "INFO",
                "filters": ["require_debug_true"],
                "class": "logging.StreamHandler",
            },
            "django.server": {
                "level": "INFO",
                "class": "logging.StreamHandler",
                "formatter": "django.server",
            },
            "mail_admins": {
                "level": "ERROR",
                "filters": ["require_debug_false"],
                "class": "django.utils.log.AdminEmailHandler",
            },
        },
        "loggers": {
            "django": {
                "handlers": ["console", "mail_admins"],
                "level": "INFO",
            },
            "django.server": {
                "handlers": ["django.server"],
                "level": "INFO",
                "propagate": False,
            },
        },
    }

Consultez Configuration de la journalisation pour savoir comment compléter ou remplacer cette configuration de journalisation par défaut.

## Extensions de journalisation de Django

Django fournit un certain nombre d’utilitaires pour gérer les exigences particulières de la journalisation dans le contexte d’un environnement de serveur web.

### Journaliseurs

Django fournit plusieurs journaliseurs intégrés :

#### `django`

Le journaliseur parent des messages dans la hiérarchie des journaliseurs nommés de Django. Django lui-même ne poste pas de messages avec ce nom. Il utilise plutôt l’un des journaliseurs ci-dessous.

#### `django.request`

Messages de journal liés au traitement des requêtes. Les réponses 5xx sont signalées comme des messages `ERROR`. Les réponses 4xx sont signalées comme des messages `WARNING`. Les requêtes journalisées vers `django.security` ne sont pas journalisées vers `django.request`.

Les messages envoyés à ce journaliseur possèdent le contexte supplémentaire suivant :

- `status_code`: le code de réponse HTTP associé à la requête.

- `request`: l’objet requête qui a généré le message de journal.

#### `django.server`

Messages de journal liés au traitement des requêtes reçues par le serveur sollicité par la commande `runserver`. Les réponses HTTP 5xx sont journalisées comme des messages `ERROR`. Les réponses 4xx sont journalisées comme des messages `WARNING`, et tout le reste est journalisé comme message `INFO`.

Les messages envoyés à ce journaliseur possèdent le contexte supplémentaire suivant :

- `status_code`: le code de réponse HTTP associé à la requête.

- `request`: l’objet requête (de type `socket.socket`) qui a généré le message de journal.

#### `django.template`

Journalise les messages liés au rendu des gabarits.

- Les variables de contexte manquantes sont journalisées comme des messages de type `DEBUG`.

#### `django.db.backends`

Messages en lien avec l’interaction entre le code et la base de données. Par exemple, chaque instruction SQL de niveau applicatif exécutée par une requête est envoyée à ce journaliseur au niveau `DEBUG`.

Les messages envoyés à ce journaliseur possèdent le contexte supplémentaire suivant :

- `duration`: le temps d’exécution de l’instruction SQL concernée.

- `sql`: l’instruction SQL exécutée.

- `params`: les paramètres utilisés dans l’appel SQL.

- `alias`: l’alias de la base de données utilisée dans l’appel SQL.

Pour des raisons de performance, la journalisation SQL n’est activée que lorsque `settings.DEBUG` est défini à `True`, peu importe le niveau de journalisation ou les gestionnaires installés.

Cette journalisation ne concerne pas l’initialisation au niveau infrastructure (par ex. `SET TIMEZONE`). Activez la journalisation des requêtes au niveau de la base de données si vous souhaitez voir toutes les requêtes à la base de données.

#### `django.utils.autoreload`

Messages de journalisation liés au code de rechargement automatique durant l’exécution du serveur de développement de Django. Ce journaliseur produit un message `INFO` lorsqu’il détecte une modification dans un fichier de code source et peut produire des messages d’avertissement `WARNING` pendant l’inspection du système de fichiers et les processus d’inscription aux évènements.

#### `django.contrib.auth`

Des message de journalisation liées à django.contrib.auth, en particulier des messages `ERROR` sont générés lorsqu’un formulaire `PasswordResetForm` est soumis avec succès mais que le courriel de réinitialisation du mot de passe ne peut pas être envoyé suite à une exception d’envoi de message.

#### `django.contrib.gis`

Messages de journalisation liés à GeoDjango à différents endroits : durant le chargement des bibliothèques géospatiales externes (GEOS, GDAL, etc.) et lors du signalement d’erreurs. Chaque entrée de journalisation `ERROR` inclut l’exception interceptée et les données contextuelles en rapport.

#### `django.dispatch`

Ce journaliseur est utilisé dans les Signaux, spécifiquement dans la classe `Signal`, pour informer des problèmes d’envoi de signaux vers un récepteur connecté. L’entrée de journal `ERROR` inclut l’exception interceptée dans `exc_info` et ajoute le contexte supplémentaire suivant :

- `receiver`: le nom du récepteur.

- `err`: l’exception générée au moment d’appeler le récepteur.

#### `django.security.*`

Les journaliseurs `security` reçoivent les messages à chaque occurrence de `SuspiciousOperation` et des autres erreurs liées à la sécurité. Il existe un sous-sérialiseur pour chaque sous-type d’erreur de sécurité, y compris toutes les `SuspiciousOperation`. Le niveau des événements journalisés dépend de l’endroit où l’exception est traitée. La plupart des occurrences sont journalisées comme des avertissements, alors que toute exception `SuspiciousOperation` atteignant le gestionnaire WSGI sera journalisée comme une erreur. Par exemple, lorsqu’un en-tête HTTP `Host` contenu dans une requête de client ne correspond pas à `ALLOWED_HOSTS`, Django renvoie une réponse 400 et un message d’erreur est journalisé dans le journaliseur `django.security.DisallowedHost`.

Ces événements de journal aboutissent par défaut dans le journaliseur `django`, qui envoie les erreurs par courriel aux administrateurs lorsque `DEBUG=False`. Les requêtes aboutissant à une réponse 400 en raison d’une erreur `SuspiciousOperation` ne sont pas journalisées dans `django.request`, mais seulement dans le journaliseur `django.security`.

Pour réduire au silence un type particulier de `SuspiciousOperation`, vous pouvez surcharger le journaliseur correspondant en suivant cet exemple :

    LOGGING = {
        # ...
        "handlers": {
            "null": {
                "class": "logging.NullHandler",
            },
        },
        "loggers": {
            "django.security.DisallowedHost": {
                "handlers": ["null"],
                "propagate": False,
            },
        },
        # ...
    }

Les autres journaliseurs `django.security` non basés sur `SuspiciousOperation` sont :

- `django.security.csrf`: pour les échecs CSRF.

#### `django.db.backends.schema`

Journalise les requêtes SQL exécutées pendant les modifications de schéma de la base de données effectuées par le système des migrations. Notez que les requêtes exécutées par `RunPython` ne sont pas journalisées. Les messages de ce journaliseur possèdent `params` et `sql` dans leur contexte complémentaire (mais pas la durée comme `django.db.backends`). Ces valeurs ont la même signification que django.db.backends l’explique.

#### `django.contrib.sessions`

Journalise les messages liés à l”infrastructure des sessions.

- Les erreurs non fatales se produisant lors de l’utilisation du moteur `django.contrib.sessions.backends.cached_db.SessionStore` sont journalisées comme messages `ERROR` avec la trace d’erreur correspondante.

### Gestionnaires

Django propose un gestionnaire de journalisation en plus de `ceux offerts par le module logging de Python`.

class AdminEmailHandler(include_html=False, email_backend=None, reporter_class=None, using=None)

  Ce gestionnaire envoie un courriel aux administrateurs du site (`ADMINS`) pour chaque message de journal qu’il reçoit.

  Si le message de journalisation contient un attribut `request`, les détails complets de la requête seront inclus dans le courriel. Le sujet du courriel contiendra « internal IP » si l’adresse IP du client se trouve dans le réglage `INTERNAL_IPS`; sinon, il contiendra « EXTERNAL IP ».

  Si la ligne de journal contient des informations sur une trace de débogage, celle-ci est incluse dans le courriel.

  Le paramètre `include_html` de `AdminEmailHandler` est utilisé pour contrôler si le courriel contenant la trace de débogage doit inclure une pièce jointe HTML contenant la page web complète de débogage qui aurait été affichée si le réglage `DEBUG` valait `True`. Pour définir cette valeur dans votre configuration, incluez ce paramètre dans la définition du gestionnaire pour `django.utils.log.AdminEmailHandler`, comme ceci :

      "handlers": {
          "mail_admins": {
              "level": "ERROR",
              "class": "django.utils.log.AdminEmailHandler",
              "include_html": True,
          },
      }

  Soyez conscient des implications sécuritaires de la journalisation lorsque vous utilisez `AdminEmailHandler`.

  Email is sent using the default mailer. This can be overridden by setting the `using` argument of `AdminEmailHandler`, like this:

      "handlers": {
          "mail_admins": {
              "level": "ERROR",
              "class": "django.utils.log.AdminEmailHandler",
              "using": "internal",
          },
      }

  If the specified mailer is not configured in the `MAILERS` setting, no email will be sent and no additional error will be raised.

  By setting the deprecated `email_backend` argument of `AdminEmailHandler`, the email backend that is being used by the handler can be overridden. `email_backend` is not supported when `MAILERS` is defined or when the `using` argument is provided.

  Le paramètre `reporter_class` de `AdminEmailHandler` permet de fournir une sous-classe de `django.views.debug.ExceptionReporter` pour personnaliser le texte de trace d’erreur envoyé dans le corps du courriel. Indiquez un chemin d’importation sous forme de chaîne vers la classe que vous souhaitez utiliser, comme ceci

      "handlers": {
          "mail_admins": {
              "level": "ERROR",
              "class": "django.utils.log.AdminEmailHandler",
              "include_html": True,
              "reporter_class": "somepackage.error_reporter.CustomErrorReporter",
          },
      }

  Changed in Django 6.1:

  The `using` argument was added.

  Obsolète depuis la version 6.1: The `email_backend` argument is deprecated. Use `using` instead.

  send_mail(subject, message, *args, **kwargs)

    Envoie des courriels aux utilisateurs administrateurs. Pour personnaliser ce comportement, vous pouvez créer une sous-classe de `AdminEmailHandler` et surcharger cette méthode.

### Filtres

Django propose quelques filtres de journalisation en plus de ceux offerts par le module `logging` de Python.

class CallbackFilter(callback)

  Ce filtre accepte une fonction de rappel (qui ne doit accepter qu’un seul paramètre, l’enregistrement à journaliser) et appelle celle-ci pour chaque enregistrement qui transite par ce filtre. Le traitement de l’enregistrement s’arrête si la fonction de rappel renvoie `False`.

  Par exemple, pour exclure `UnreadablePostError` (généré lorsqu’un utilisateur annule un téléversement) des courriels envoyés aux administrateurs, cette fonction de filtre pourrait être créée :

      from django.http import UnreadablePostError

      def skip_unreadable_post(record):
          if record.exc_info:
              exc_type, exc_value = record.exc_info[:2]
              if isinstance(exc_value, UnreadablePostError):
                  return False
          return True

  puis ajoutée à la configuration de journalisation :

      LOGGING = {
          # ...
          "filters": {
              "skip_unreadable_posts": {
                  "()": "django.utils.log.CallbackFilter",
                  "callback": skip_unreadable_post,
              },
          },
          "handlers": {
              "mail_admins": {
                  "level": "ERROR",
                  "filters": ["skip_unreadable_posts"],
                  "class": "django.utils.log.AdminEmailHandler",
              },
          },
          # ...
      }

class RequireDebugFalse

  Ce filtre ne laisse passer les enregistrements que lorsque `settings.DEBUG` vaut `False`.

  Ce filtre est utilisé comme le montre l’exemple ci-dessous dans la configuration par défaut de `LOGGING` pour garantir que `AdminEmailHandler` n’envoie des courriels d’erreur aux administrateurs que lorsque `DEBUG` vaut `False`:

      LOGGING = {
          # ...
          "filters": {
              "require_debug_false": {
                  "()": "django.utils.log.RequireDebugFalse",
              },
          },
          "handlers": {
              "mail_admins": {
                  "level": "ERROR",
                  "filters": ["require_debug_false"],
                  "class": "django.utils.log.AdminEmailHandler",
              },
          },
          # ...
      }

class RequireDebugTrue

  Ce filtre est similaire à `RequireDebugFalse`, sauf que les enregistrements ne sont retransmis que lorsque `DEBUG` vaut `True`.