日志¶
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
:生成日志消息的请求对象(一个socket.socket
)。
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
¶
与 GeoDjango 相关的日志消息在各个时刻:在加载外部地理空间库(GEOS、GDAL 等)和报告错误时。每个 ERROR
日志记录都包括捕获的异常和相关的上下文数据。
django.dispatch
¶
这个记录器在 信号 中使用,特别是在 Signal
类中,用于在将信号分派给连接的接收器时报告问题。ERROR
日志记录包括捕获的异常作为 exc_info
并添加以下额外的上下文:
receiver
:接收器的名称。err
:调用接收器时发生的异常。
django.security.*
¶
安全记录器将接收任何发生 SuspiciousOperation
和其他安全相关错误的消息。每个子类型的安全错误都有一个子记录器,包括所有 SuspiciousOperation
s。日志事件的级别取决于异常处理的位置。 大多数发生的事件被记录为警告,而任何到达 WSGI 处理程序的 SuspiciousOperation
将被记录为错误。例如,当客户端的请求中包含一个 HTTP Host
头,而这个头不符合 ALLOWED_HOSTS
时,Django 会返回一个 400 的响应,并且错误信息会被记录到 django.security.DisallowedHost
记录器中。
这些日志事件默认会到达 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
¶
Log messages related to the session framework.
Non-fatal errors occurring when using the
django.contrib.sessions.backends.cached_db.SessionStore
engine are logged asERROR
messages with the corresponding traceback.
Handlers¶
除了 Python 日志模块提供的处理程序外,Django 还提供了一个日志处理程序。
- class AdminEmailHandler(include_html=False, email_backend=None, reporter_class=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
时要注意 日志记录的安全性影响。通过设置
AdminEmailHandler
的email_backend
参数,处理程序使用的 email 后端 可以被覆盖,就像这样:"handlers": { "mail_admins": { "level": "ERROR", "class": "django.utils.log.AdminEmailHandler", "email_backend": "django.core.mail.backends.filebased.EmailBackend", }, }
默认情况下,将使用
EMAIL_BACKEND
中指定的电子邮件后端实例。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", }, }
- 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
时才会传递记录。