# Django 6.0.7 documentation

# 日志

See also

- 如何配置和使用日志

- Django 日志概览

Django 的日志模块扩展了 Python 内置的 `logging`。

日志记录是作为 Django 的通用 `django.setup()` 函数的一部分进行配置的，因此除非明确禁用，否则始终可用。

## Django 的默认日志配置

默认情况下，Django 使用 Python 的 logging.config.dictConfig 格式。

### 默认的日志记录条件

完整的默认日志记录条件如下：

当 `DEBUG` 为 `True` 时：

- `django` 记录器将 `django` 层次结构（`django.server` 除外）中的 `INFO` 级别或更高的消息发送到控制台。

当 `DEBUG` 为 `False` 时：

- `django` 记录器将 `django` 层次结构（`django.server` 除外）中带有 `ERROR` 或 `CRITICAL` 级别的消息发送到 `AdminEmailHandler`。

无论 `DEBUG` 的值如何：

- django.server 记录器向控制台发送 `INFO` 或更高等级的消息。

除了 django.server 之外，所有的日志记录器都会将日志记录传播给它们的父辈，直到 `django` 的根日志记录器。`console` 和 `mail_admins` 处理程序被附加到根记录器上，以提供上述行为。

Python 的默认设置会将级别为 `WARNING` 及更高级别的记录发送到控制台。

### 默认的日志定义

Django 的默认日志配置继承了 Python 的默认设置。它以 `django.utils.log.DEFAULT_LOGGING` 的形式可用，并在 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,
            },
        },
    }

请参阅 日志模块的配置 了解如何补充或替换此默认日志配置。

## Django 日志扩展

Django 提供了许多工具来处理在 Web 服务器环境中的日志记录特定要求。

### Loggers

Django 提供了几种内置的记录器。

#### `django`

在 `django` 命名的日志层次结构 中，用于消息的父日志记录器。Django 不使用这个名称发布消息。而是使用以下其中一个日志记录器。

#### `django.request`

记录与处理请求有关的信息。5XX 的响应以 `ERROR` 消息的形式出现；4XX 的响应以 `WARNING` 消息的形式出现。记录在 `django.security` 记录器中的请求不会记录在 `django.request` 中。

发送给此记录器的消息有以下额外的上下文：

- `status_code`：与请求相关的 HTTP 响应代码。

- `request`：产生记录信息的请求对象。

#### `django.server`

记录与处理由 `runserver` 命令调用的服务器收到的请求有关的消息。HTTP 5XX 响应被记录为 `ERROR` 消息，4XX 响应被记录为 `WARNING` 消息，其他所有消息被记录为 `INFO`。

发送给此记录器的消息有以下额外的上下文：

- `status_code`：与请求相关的 HTTP 响应代码。

- `request`: The request object (a `socket.socket`) that generated the logging message.

#### `django.template`

记录与模板渲染相关的消息。

- 缺少的上下文变量会被记录为 `DEBUG` 消息。

#### `django.db.backends`

与代码与数据库互动有关的信息。例如，请求执行的每一条应用程序级别的 SQL 语句都会以 `DEBUG` 级别记录到这个记录器。

发送给此记录器的消息有以下额外的上下文：

- `duration`：执行 SQL 语句所需时间。

- `sql`：所执行的 SQL 语句。

- `params`：SQL 调用中使用的参数。

- `alias`：SQL 调用中使用的数据库的别名。

出于性能考虑，只有当 `settings.DEBUG` 设置为 `True` 时，才会启用 SQL 日志记录，而不考虑日志级别或安装的处理程序。

这个日志记录不包括框架级别的初始化（例如 `SET TIMEZONE`）。如果希望查看所有数据库查询，请在数据库中启用查询日志记录。

#### `django.utils.autoreload`

与 Django 开发服务器执行期间自动代码重新加载相关的日志消息。此记录器在检测到源代码文件的修改时生成 `INFO` 消息，并在文件系统检查和事件订阅过程中可能生成 `WARNING` 消息。

#### `django.contrib.auth`

Log messages related to django.contrib.auth, particularly `ERROR` messages are generated when a `PasswordResetForm` is successfully submitted but the password reset email cannot be delivered due to a mail sending exception.

#### `django.contrib.gis`

Log messages related to GeoDjango at various points: during the loading of external GeoSpatial libraries (GEOS, GDAL, etc.) and when reporting errors. Each `ERROR` log record includes the caught exception and relevant contextual data.

#### `django.dispatch`

This logger is used in 信号, specifically within the `Signal` class, to report issues when dispatching a signal to a connected receiver. The `ERROR` log record includes the caught exception as `exc_info` and adds the following extra context:

- `receiver`：接收器的名称。

- `err`：调用接收器时发生的异常。

#### `django.security.*`

The security loggers will receive messages on any occurrence of `SuspiciousOperation` and other security-related errors. There is a sub-logger for each subtype of security error, including all `SuspiciousOperation`s. The level of the log event depends on where the exception is handled. Most occurrences are logged as a warning, while any `SuspiciousOperation` that reaches the WSGI handler will be logged as an error. For example, when an HTTP `Host` header is included in a request from a client that does not match `ALLOWED_HOSTS`, Django will return a 400 response, and an error message will be logged to the `django.security.DisallowedHost` logger.

这些日志事件默认会到达 `django` 日志器，当 `DEBUG=False` 时，记录器会将错误事件发送给管理员。由于 `SuspiciousOperation` 导致 400 响应的请求不会被记录到 `django.request` 记录器，而只会记录到 `django.security` 记录器。

要使某一特定类型的 `SuspiciousOperation` 保持沉默，你可以按照以下示例覆盖该特定的记录器：

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

其他不基于 `SuspiciousOperation` 的 `django.security` 记录器是：

- `django.security.csrf`：用于 CSRF 错误。

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

记录 migrations framework 对数据库进行模式变更时执行的 SQL 查询。请注意，它不会记录 `RunPython` 执行的查询。给这个记录器的消息在其额外的上下文中有 `params` 和 `sql` （但与 `django.db.backends` 不同，不是 duration）。这些值的含义与 django.db.backends 中的解释相同。

#### `django.contrib.sessions`

与 会话框架 相关的日志消息。

- 使用 `django.contrib.sessions.backends.cached_db.SessionStore` 引擎时发生的非致命错误会记录为 `ERROR` 消息，并带有相应的回溯。

### Handlers

除了 Python 日志模块提供的处理程序外，Django 还提供了一个日志处理程序。

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

  该处理程序对收到的每条日志消息都会向站点 `ADMINS` 发送一封邮件。

  如果日志记录中包含 `request` 属性，电子邮件中会包含请求的全部细节。如果客户的 IP 地址在 `INTERNAL_IPS` 设置中，电子邮件主题将包括“内部 IP”；如果没有，则包括“外部 IP”。

  如果日志记录中包含堆栈跟踪信息，该堆栈跟踪信息将包含在电子邮件中。

  `AdminEmailHandler` 的 `include_html` 参数用于控制是否在 traceback 邮件中包含一个 HTML 附件，该附件包含了如果 `DEBUG` 为 `True` 时会生成的完整调试网页的内容。要在配置中设置此值，将其包含在 `django.utils.log.AdminEmailHandler` 的处理程序定义中，如下所示：

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

  在使用 `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.

  `AdminEmailHandler` 的 `reporter_class` 参数允许提供一个 `django.view.debug.ExceptionReporter` 子类来自定义邮件正文中发送的回溯文本。你提供一个字符串的导入路径到你想使用的类，像这样：

      "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.

  Deprecated since version 6.1: The `email_backend` argument is deprecated. Use `using` instead.

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

    向管理员用户发送邮件。要自定义这个行为，你可以将 `AdminEmailHandler` 类子类化，并覆盖这个方法。

### 过滤器

除了 Python 日志模块提供的日志过滤器外，Django 还提供了一些日志过滤器。

class CallbackFilter(callback)

  这个过滤器接受一个回调函数（它应该接受一个单一的参数，即要记录的记录），并对每个通过过滤器的记录进行调用。如果回调函数返回 False，则不会对该记录进行处理。

  例如，要从管理员邮件中过滤掉 `UnreadablePostError` （当用户取消上传时引发），你可以创建一个过滤函数：

      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

  然后将其添加到你的日志记录配置中：

      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

  只有当 settings.DEBUG 为 False 时，该过滤器才会传递记录。

  该过滤器在默认的 `logging` 配置中使用如下，以确保 `AdminEmailHandler` 只在 `DEBUG` 为 `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

  该过滤器类似于 `RequireDebugFalse`，但只有当 `DEBUG` 为 `True` 时才会传递记录。