日志
参见
Django’s logging module extends Python’s builtin logging.
Logging is configured as part of the general Django django.setup() function, so it’s always available unless explicitly disabled.
Django 的默认日志配置
By default, Django uses Python’s logging.config.dictConfig format.
Default logging conditions
The full set of default logging conditions are:
当 DEBUG 为 True
时:
django
记录器将django
层次结构(django.server
除外)中的INFO
级别或更高的消息发送到控制台。
当 DEBUG 为 False
时:
django
记录器将django
层次结构(django.server
除外)中带有ERROR
或CRITICAL
级别的消息发送到 AdminEmailHandler。
Independently of the value of DEBUG:
- django.server 记录器向控制台发送
INFO
或更高等级的消息。
除了 django.server 之外,所有的日志记录器都会将日志记录传播给它们的父辈,直到 django
的根日志记录器。console
和 mail_admins
处理程序被附加到根记录器上,以提供上述行为。
Python’s own defaults send records of level WARNING
and higher to the console.
Default logging definition
Django’s default logging configuration inherits Python’s defaults. It’s available as django.utils.log.DEFAULT_LOGGING
and defined in 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,
},
},
}
See 日志模块的配置 on how to complement or replace this default logging configuration.
Django logging extensions
Django provides a number of utilities to handle the particular requirements of logging in a web server environment.
Loggers
Django 提供了几种内置的记录器。
django
The parent logger for messages in the django
named logger hierarchy. Django does not post messages using this name. Instead, it uses one of the loggers below.
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
: The alias of the database used in the SQL call.
出于性能考虑,只有当 settings.DEBUG
设置为 True
时,才会启用 SQL 日志记录,而不考虑日志级别或安装的处理程序。
This logging does not include framework-level initialization (e.g. SET TIMEZONE
). Turn on query logging in your database if you wish to view all database queries.
Changed in Django 4.2:
Support for logging transaction management queries (BEGIN
, COMMIT
, and ROLLBACK
) was added.
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 中的解释相同。
Handlers
Django provides one log handler in addition to those provided by the Python logging module.
class AdminEmailHandler
(include_html=False, email_backend=None, reporter_class=None)
该处理程序对收到的每条日志消息都会向站点 ADMINS 发送一封邮件。
如果日志记录中包含 request
属性,电子邮件中会包含请求的全部细节。如果客户的 IP 地址在 INTERNAL_IPS 设置中,电子邮件主题将包括“内部 IP”;如果没有,则包括“外部 IP”。
如果日志记录中包含堆栈跟踪信息,该堆栈跟踪信息将包含在电子邮件中。
The include_html
argument of AdminEmailHandler
is used to control whether the traceback email includes an HTML attachment containing the full content of the debug web page that would have been produced if DEBUG were True
. To set this value in your configuration, include it in the handler definition for django.utils.log.AdminEmailHandler
, like this:
"handlers": {
"mail_admins": {
"level": "ERROR",
"class": "django.utils.log.AdminEmailHandler",
"include_html": True,
},
}
Be aware of the security implications of logging when using the 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
时才会传递记录。