---
title: "日志"
version: 6.1
locale: zh-hans
source: https://docs.djangoproject.com/zh-hans/6.1/ref/logging/
canonical: https://djangodocs.dev/zh-hans/6.1/ref/logging/
---
# 日志

> **See also**
>
> - [如何配置和使用日志](/zh-hans/6.1/howto/logging/#logging-how-to)
> - [Django 日志概览](/zh-hans/6.1/topics/logging/#logging-explanation)

Django 的日志模块扩展了 Python 内置的 [`logging`](https://docs.python.org/3/library/logging.html#module-logging)。

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

## Django 的默认日志配置

默认情况下，Django 使用 Python 的 [logging.config.dictConfig 格式](https://docs.python.org/3/library/logging.config.html#logging-config-dictschema)。

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

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

当 [`DEBUG`](/zh-hans/6.1/ref/settings/#std-setting-DEBUG) 为 `True` 时：

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

当 [`DEBUG`](/zh-hans/6.1/ref/settings/#std-setting-DEBUG) 为 `False` 时：

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

无论 [`DEBUG`](/zh-hans/6.1/ref/settings/#std-setting-DEBUG) 的值如何：

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

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

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

### 默认的日志定义

Django 的默认日志配置继承了 Python 的默认设置。它以 `django.utils.log.DEFAULT_LOGGING` 的形式可用，并在 [django/utils/log.py](https://github.com/django/django/blob/stable/6.1.x/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,
        },
    },
}
```

请参阅 [日志模块的配置](/zh-hans/6.1/topics/logging/#configuring-logging) 了解如何补充或替换此默认日志配置。

## Django 日志扩展

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

### Loggers

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

#### `django`

在 `django` [命名的日志层次结构](/zh-hans/6.1/howto/logging/#naming-loggers-hierarchy) 中，用于消息的父日志记录器。Django 不使用这个名称发布消息。而是使用以下其中一个日志记录器。

#### `django.request`

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

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

- `status_code`：与请求相关的 HTTP 响应代码。
- `request`：产生记录信息的请求对象。

#### `django.server`

记录与处理由 [`runserver`](/zh-hans/6.1/ref/django-admin/#django-admin-runserver) 命令调用的服务器收到的请求有关的消息。HTTP 5XX 响应被记录为 `ERROR` 消息，4XX 响应被记录为 `WARNING` 消息，其他所有消息被记录为 `INFO`。

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

- `status_code`：与请求相关的 HTTP 响应代码。
- `request`: The request object (a [`socket.socket`](https://docs.python.org/3/library/socket.html#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](/zh-hans/6.1/ref/contrib/auth/), particularly `ERROR`
messages are generated when a
[`PasswordResetForm`](/zh-hans/6.1/topics/auth/default/#django.contrib.auth.forms.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](/zh-hans/6.1/ref/contrib/gis/) 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 [信号](/zh-hans/6.1/ref/signals/), specifically within the
[`Signal`](/zh-hans/6.1/topics/signals/#django.dispatch.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`](/zh-hans/6.1/ref/exceptions/#django.core.exceptions.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`](/zh-hans/6.1/ref/settings/#std-setting-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 错误](/zh-hans/6.1/howto/csrf/#csrf-rejected-requests)。

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

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

#### `django.contrib.sessions`

与 [会话框架](/zh-hans/6.1/topics/http/sessions/) 相关的日志消息。

- 使用 [`django.contrib.sessions.backends.cached_db.SessionStore`](/zh-hans/6.1/topics/http/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`](/zh-hans/6.1/ref/settings/#std-setting-ADMINS) 发送一封邮件。

如果日志记录中包含 `request` 属性，电子邮件中会包含请求的全部细节。如果客户的 IP 地址在 [`INTERNAL_IPS`](/zh-hans/6.1/ref/settings/#std-setting-INTERNAL_IPS) 设置中，电子邮件主题将包括“内部 IP”；如果没有，则包括“外部 IP”。

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

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

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

在使用 `AdminEmailHandler` 时要注意 [日志记录的安全性影响](/zh-hans/6.1/topics/logging/#logging-security-implications)。

Email is sent using the default [mailer](/zh-hans/6.1/topics/email/#topic-email-configuration).
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`](/zh-hans/6.1/ref/settings/#std-setting-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](/zh-hans/6.1/topics/email/#topic-email-backends) that
is being used by the handler can be overridden. `email_backend` is not
supported when [`MAILERS`](/zh-hans/6.1/ref/settings/#std-setting-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 Django 6.1**
>
> Deprecated since version 6.1: The `email_backend` argument is deprecated. Use `using` instead.

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

向管理员用户发送邮件。要自定义这个行为，你可以将 [`AdminEmailHandler`](#django.utils.log.AdminEmailHandler) 类子类化，并覆盖这个方法。

### 过滤器

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

#### `class CallbackFilter(callback)`

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

例如，要从管理员邮件中过滤掉 [`UnreadablePostError`](/zh-hans/6.1/ref/exceptions/#django.http.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`](#django.utils.log.AdminEmailHandler) 只在 [`DEBUG`](/zh-hans/6.1/ref/settings/#std-setting-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`](#django.utils.log.RequireDebugFalse)，但只有当 [`DEBUG`](/zh-hans/6.1/ref/settings/#std-setting-DEBUG) 为 `True` 时才会传递记录。
