# documentación de Django - 5.2.8

# Logging

Ver también

- How to configure and use logging

- Django logging reference

Los programadores de Python a menudo usan `print()` en su código como una herramienta de depuración rápida y conveniente. Usar el marco de registro es solo un poco más de esfuerzo que eso, pero es mucho más elegante y flexible. Además de ser útil para la depuración, el registro también puede brindarle más información, y mejor estructurada, sobre el estado y la salud de su aplicación.

## Información general

Django usa y extiende el módulo `logging` incorporado de Python para realizar el registro del sistema. Este módulo se analiza en detalle en la propia documentación de Python; esta sección proporciona una descripción general rápida.

### Rol de los recursos

Una configuración de registro de Python consta de cuatro partes:

- Loggers

- Handlers

- Filtros

- Formateadores

#### Loggers

Un logger es el punto de entrada al sistema de registro. Cada logger es un depósito con nombre en el que se pueden escribir mensajes para su procesamiento.

Un logger está configurado para tener un nivel de registro. Este nivel de registro describe la gravedad de los mensajes que manejará el logger. Python define los siguientes niveles de registro:

- `DEBUG`: Información del sistema de bajo nivel con fines de depuración

- `INFO`: Información general del sistema

- `WARNING`: Información que describe un problema menor que ha ocurrido.

- `ERROR`: Información que describe un problema mayor que ha ocurrido.

- `CRÍTICO`: Información que describe un problema crítico que ha ocurrido.

Cada mensaje que se escribe en el logger es un Registro del logger. Cada registro también tiene un nivel de registro que indica la gravedad de ese mensaje específico. Un registro de logger también puede contener metadatos útiles que describen el evento que se está registrando. Esto puede incluir detalles como un seguimiento de la pila o un código de error.

Cuando se envía un mensaje al logger, el nivel de registro del mensaje se compara con el nivel de registro del logger. Si el nivel de registro del mensaje alcanza o supera el nivel de registro del propio logger, el mensaje se someterá a un procesamiento adicional. Si no es así, el mensaje será ignorado.

Una vez que un logger ha determinado que un mensaje debe procesarse, se pasa a un Handler.

#### Handlers

El handler es el motor que determina qué sucede con cada mensaje en un logger. Describe un comportamiento de registro particular, como escribir un mensaje en la pantalla, en un archivo o en un socket de red.

Al igual que los loggers, los handlers también tienen un nivel de registro. Si el nivel de registro de una entrada de registro no alcanza o excede el nivel del controlador, el controlador ignorará el mensaje.

Un logger puede tener varios handlers y cada handlers puede tener un nivel de registro diferente. De esta forma, es posible proporcionar diferentes formas de notificación dependiendo de la importancia de un mensaje. Por ejemplo, podría instalar un controlador que reenvíe los mensajes `ERROR` y `CRITICAL` a un servicio de paginación, mientras que un segundo controlador registra todos los mensajes (incluidos los mensajes `ERROR` y `CRITICAL`) a un archivo para su posterior análisis.

#### Filtros

Se utiliza un filtro para proporcionar un control adicional sobre qué entradas de registro se pasan del registrador al controlador.

De manera predeterminada, se manejará cualquier mensaje de registro que cumpla con los requisitos de nivel de registro. Sin embargo, al instalar un filtro, puede colocar criterios adicionales en el proceso de registro. Por ejemplo, podrías instalar un filtro que solo permita que se emitan mensajes `ERROR` de una fuente en particular.

Los filtros también se pueden usar para modificar el registro de registro antes de que se emita. Por ejemplo, podría escribir un filtro que rebaje los registros de registro `ERROR` a registros `WARNING` si se cumple un conjunto particular de criterios.

Los filtros se pueden instalar en loggers o en handlers; se pueden usar múltiples filtros en una cadena para realizar múltiples acciones de filtrado.

#### Formateadores

En última instancia, un registro debe representarse como texto. Los Formatters describen el formato exacto de ese texto. Un formateador generalmente consta de una cadena de formato de Python que contiene atributos LogRecord;

## Implicaciones de seguridad

El sistema de registro maneja información potencialmente confidencial. Por ejemplo, el registro puede contener información sobre una solicitud web o un seguimiento de pila, mientras que algunos de los datos que recopila en sus propios loggers también pueden tener implicaciones de seguridad. Debes asegurarte de saber:

- qué información se recopila

- donde se almacenará posteriormente

- cómo se transferirá

- quien pudiera tener acceso a ella.

Para ayudar a controlar la recopilación de información confidencial, puede designar explícitamente cierta información confidencial para que se filtre de los informes de errores. Obtenga más información sobre cómo filtrar informes de errores.

### `AdminEmailHandler`

La `AdminEmailHandler` integrada merece una mención en el contexto de la seguridad. Si su opción `include_html` está habilitada, el mensaje de correo electrónico que envía contendrá un rastreo completo, con nombres y valores de variables locales en cada nivel de la pila, además de los valores de su configuración de Django (en otras palabras, el mismo nivel de detalle que se expone en una página web cuando `DEBUG` es `True`).

Por lo general, no se considera una buena idea enviar información potencialmente confidencial por correo electrónico. En su lugar, considere utilizar uno de los muchos servicios de terceros a los que se pueden enviar registros detallados para obtener lo mejor de múltiples mundos: la rica información de rastreos completos, una gestión clara de quién recibe notificaciones y tiene acceso a la información, etc. .

## Configuración de registro

La biblioteca de registro de Python proporciona varias técnicas para configurar el registro, que van desde una interfaz programática hasta archivos de configuración. Por defecto, Django usa el formato dictConfig.

Para configurar el registro, utilice `LOGGING` para definir un diccionario de configuración de registro. Esta configuración describe los loggers, handlers, filtros y formateadores que desea en su configuración de registro, y los niveles de registro y otras propiedades que desea que tengan esos componentes.

De forma predeterminada, la configuración de `LOGGING` se fusiona con La configuración de registro predeterminada de Django utilizando el siguiente esquema.

Si la llave `disable_existing_loggers` en `LOGGING` dictConfig se establece como `True` (que es el valor predeterminado de `dictConfig` si falta la llave), entonces todos los loggers de la configuración predeterminada serán desactivados. Los loggers deshabilitados no son lo mismo que los eliminados; el logger seguirá existiendo, pero descartará silenciosamente todo lo registrado en él, ni siquiera propagará las entradas a un logger principal. Por lo tanto, debe tener mucho cuidado al usar `'disable_existing_loggers': True`; probablemente no sea lo que quieres. En su lugar, puede establecer `disable_existing_loggers` como `False` y redefinir algunos o todos los loggers predeterminados; o puede establecer `LOGGING_CONFIG` como `None` y manejar la configuración de registro usted mismo.

El registro se configura como parte de la función `setup()` general de Django. Por lo tanto, puede estar seguro de que los loggers siempre estarán listos para usar en el código de su proyecto.

### Ejemplos

La documentación completa para dictConfig format es la mejor fuente de información sobre el registro de diccionarios de configuración. Sin embargo, para darle una idea de lo que es posible, aquí hay varios ejemplos.

Para comenzar, aquí hay una pequeña configuración que le permitirá enviar todos los mensajes de registro a la consola:

`settings.py`

    import os

    LOGGING = {
        "version": 1,
        "disable_existing_loggers": False,
        "handlers": {
            "console": {
                "class": "logging.StreamHandler",
            },
        },
        "root": {
            "handlers": ["console"],
            "level": "WARNING",
        },
    }

Esto configura el logger principal `root` para enviar mensajes con el nivel `WARNING` y superior al controlador de la consola. Ajustando el nivel a `INFO` o `DEBUG` puedes mostrar más mensajes. Esto puede ser útil durante el desarrollo.

A continuación, podemos agregar un registro más detallado. Aquí hay un ejemplo de cómo hacer que el sistema de registro imprima más mensajes solo del registrador llamado django:

`settings.py`

    import os

    LOGGING = {
        "version": 1,
        "disable_existing_loggers": False,
        "handlers": {
            "console": {
                "class": "logging.StreamHandler",
            },
        },
        "root": {
            "handlers": ["console"],
            "level": "WARNING",
        },
        "loggers": {
            "django": {
                "handlers": ["console"],
                "level": os.getenv("DJANGO_LOG_LEVEL", "INFO"),
                "propagate": False,
            },
        },
    }

Por defecto, esta configuración envía mensajes desde el logger `django` de nivel `INFO` o superior a la consola. Este es el mismo nivel que la configuración de registro predeterminada de Django, excepto que la configuración predeterminada solo muestra los registros cuando `DEBUG=True`. Django no registra muchos de estos mensajes de nivel `INFO`. Sin embargo, con esta configuración, también puede configurar la variable de entorno `DJANGO_LOG_LEVEL=DEBUG` para ver todo el registro de depuración de Django, que es muy detallado ya que incluye todas las consultas de la base de datos.

No tienes que iniciar sesión en la consola. Aquí hay una configuración que escribe todos los registros del registrador llamado django en un archivo local:

`settings.py`

    LOGGING = {
        "version": 1,
        "disable_existing_loggers": False,
        "handlers": {
            "file": {
                "level": "DEBUG",
                "class": "logging.FileHandler",
                "filename": "/path/to/django/debug.log",
            },
        },
        "loggers": {
            "django": {
                "handlers": ["file"],
                "level": "DEBUG",
                "propagate": True,
            },
        },
    }

Si usa este ejemplo, asegúrese de cambiar la ruta `'filename` a una ubicación en la que pueda escribir el usuario que está ejecutando la aplicación Django.

Finalmente, aquí hay un ejemplo de una configuración de registro bastante compleja:

`settings.py`

    LOGGING = {
        "version": 1,
        "disable_existing_loggers": False,
        "formatters": {
            "verbose": {
                "format": "{levelname} {asctime} {module} {process:d} {thread:d} {message}",
                "style": "{",
            },
            "simple": {
                "format": "{levelname} {message}",
                "style": "{",
            },
        },
        "filters": {
            "special": {
                "()": "project.logging.SpecialFilter",
                "foo": "bar",
            },
            "require_debug_true": {
                "()": "django.utils.log.RequireDebugTrue",
            },
        },
        "handlers": {
            "console": {
                "level": "INFO",
                "filters": ["require_debug_true"],
                "class": "logging.StreamHandler",
                "formatter": "simple",
            },
            "mail_admins": {
                "level": "ERROR",
                "class": "django.utils.log.AdminEmailHandler",
                "filters": ["special"],
            },
        },
        "loggers": {
            "django": {
                "handlers": ["console"],
                "propagate": True,
            },
            "django.request": {
                "handlers": ["mail_admins"],
                "level": "ERROR",
                "propagate": False,
            },
            "myproject.custom": {
                "handlers": ["console", "mail_admins"],
                "level": "INFO",
                "filters": ["special"],
            },
        },
    }

Esta configuración de registro hace lo siguiente:

- Identifica la configuración como si estuviera en el formato “dictConfig versión 1”. Actualmente, esta es la única versión en formato dictConfig.

- Define dos formateadores:

  - `simple`, que genera el nombre del nivel de registro (por ejemplo, `DEBUG`) y el mensaje de registro.

    La cadena `format` es una cadena de formato normal de Python que describe los detalles que se generarán en cada línea de registro. La lista completa de detalles que se pueden generar se puede encontrar en Formatter Objects.

  - `verbose`, que genera el nombre del nivel de registro, el mensaje de registro, además de la hora, el proceso, el subproceso y el módulo que generan el mensaje de registro.

- Define dos filtros:

  - `project.logging.SpecialFilter`, usando el alias `special`. Si este filtro requiere argumentos adicionales, se pueden proporcionar como claves adicionales en el diccionario de configuración del filtro. En este caso, al argumento `foo` se le dará un valor de `bar` al instanciar `SpecialFilter`.

  - `django.utils.log.RequireDebugTrue`, que transmite registros cuando `DEBUG` es `True`.

- Define dos handlers:

  - `console`, una `StreamHandler`, que imprime cualquier mensaje `INFO` (o superior) en `sys.stderr`. Este handler usa el formato de salida `simple`.

  - `mail_admins`, una `AdminEmailHandler`, que envía por correo electrónico cualquier mensaje `ERROR` (o superior) al sitio `ADMINS`. Este handler usa el filtro `especial`.

- Configura tres loggers:

  - `django`, que pasa todos los mensajes al handler `console`.

  - `django.request`, que pasa todos los mensajes `ERROR` al handler `mail_admins`. Además, este logger está marcado para no propagar mensajes. Esto significa que los mensajes de registro escritos en `django.request` no serán manejados por el logger `django`.

  - `myproject.custom`, que pasa todos los mensajes en `INFO` o superior que también pasan el filtro `especial` a dos handlers: `console` y `mail_admins`. Esto significa que todos los mensajes de nivel `INFO` (o superior) se imprimirán en la consola; Los mensajes `ERROR` y `CRITICAL` también se enviarán por correo electrónico.

### Configuración de registro personalizada

Si no desea utilizar el formato dictConfig de Python para configurar su logger, puede especificar su propio esquema de configuración.

The `LOGGING_CONFIG` setting defines the callable that will be used to configure Django’s loggers. By default, it points at Python’s `logging.config.dictConfig()` function. However, if you want to use a different configuration process, you can use any other callable that takes a single argument. The contents of `LOGGING` will be provided as the value of that argument when logging is configured.

### Deshabilitar la configuración de registro

Si no desea configurar el registro en absoluto (o desea configurar manualmente el registro utilizando su propio enfoque), puede establecer `LOGGING_CONFIG` como `None`. Esto deshabilitará el proceso de configuración para el registro predeterminado de Django.

Establecer `LOGGING_CONFIG` como `None` solo significa que el proceso de configuración automática está deshabilitado, no el registro en sí. Si deshabilita el proceso de configuración, Django aún realizará llamadas de registro, recurriendo al comportamiento de registro predeterminado que esté definido.

Aquí hay un ejemplo que deshabilita la configuración de registro de Django y luego configura manualmente el registro:

`settings.py`

    LOGGING_CONFIG = None

    import logging.config

    logging.config.dictConfig(...)

Tenga en cuenta que el proceso de configuración predeterminado solo llama a `LOGGING_CONFIG` una vez que la configuración está completamente cargada. Por el contrario, configurar manualmente el inicio de sesión en su archivo de configuración cargará su configuración de inicio de sesión inmediatamente. Como tal, su configuración de registro debe aparecer después de cualquier configuración de la que dependa.