日志记录

Django 的日志记录模块扩展了 Python 的内置 logging

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

Django 的默认日志记录配置

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

默认日志记录条件

完整的默认日志记录条件集是:

DEBUGTrue

  • django 日志记录器以 INFO 级别或更高级别将 django 层次结构中的消息(django.server 除外)发送到控制台。

DEBUGFalse

  • django 日志记录器以 ERRORCRITICAL 级别将 django 层次结构中的消息(django.server 除外)发送到 AdminEmailHandler

独立于 DEBUG 的值

  • django.server 日志记录器以 INFO 级别或更高级别将消息发送到控制台。

django.server 之外的所有日志记录器都将其日志记录传播到其父级,直到根 django 日志记录器。 consolemail_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 服务器环境中日志记录的特定需求。

日志记录器

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

Django 4.2.16 中的新功能。

django.contrib.auth 相关的日志消息,特别是当 PasswordResetForm 成功提交但由于邮件发送异常无法发送密码重置邮件时生成的 ERROR 消息。

django.contrib.gis

GeoDjango 在各个方面的日志消息:在加载外部地理空间库(GEOS、GDAL 等)期间以及在报告错误时。每个 ERROR 日志记录都包含捕获的异常和相关的上下文数据。

django.dispatch

此日志记录器用于信号,特别是在Signal类中,用于报告向已连接接收器分派信号时遇到的问题。ERROR日志记录包含捕获的异常作为exc_info,并添加以下额外上下文

  • receiver:接收器的名称。

  • err:调用接收器时发生的异常。

django.security.*

安全日志记录器将在发生SuspiciousOperation和其他安全相关错误时接收消息。每个类型的安全错误都有一个子日志记录器,包括所有SuspiciousOperation。日志事件的级别取决于异常的处理位置。大多数事件都记录为警告,而任何到达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,
        },
    },
    # ...
}

其他非基于SuspiciousOperationdjango.security日志记录器:

django.db.backends.schema

记录迁移框架对数据库进行模式更改时执行的SQL查询。请注意,它不会记录由RunPython执行的查询。此日志记录器的消息在其额外上下文中包含paramssql(但与django.db.backends不同,不包含持续时间)。这些值与django.db.backends中解释的含义相同。

django.contrib.sessions

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

处理器

除了Python logging 模块提供的那些之外,Django还提供了一个日志处理器。

class AdminEmailHandler(include_html=False, email_backend=None, reporter_class=None)[source]

此处理器会为其接收到的每个日志消息向站点ADMINS发送一封电子邮件。

如果日志记录包含request属性,则请求的完整详细信息将包含在电子邮件中。如果客户端的IP地址在INTERNAL_IPS设置中,则电子邮件主题将包含短语“内部IP”;否则,它将包含“外部IP”。

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

AdminEmailHandlerinclude_html参数用于控制回溯电子邮件是否包含HTML附件,其中包含如果DEBUGTrue则会生成的调试网页的全部内容。要在配置中设置此值,请将其包含在django.utils.log.AdminEmailHandler的处理程序定义中,如下所示

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

请注意使用AdminEmailHandler时的日志记录的安全隐患

通过设置AdminEmailHandleremail_backend参数,可以使用户可以覆盖处理器使用的电子邮件后端,如下所示

"handlers": {
    "mail_admins": {
        "level": "ERROR",
        "class": "django.utils.log.AdminEmailHandler",
        "email_backend": "django.core.mail.backends.filebased.EmailBackend",
    },
}

默认情况下,将使用EMAIL_BACKEND中指定的电子邮件后端的实例。

AdminEmailHandlerreporter_class参数允许提供一个django.views.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)[source]

向管理员用户发送电子邮件。要自定义此行为,您可以对AdminEmailHandler类进行子类化并重写此方法。

过滤器

除了Python logging模块提供的那些过滤器之外,Django还提供了一些日志过滤器。

class CallbackFilter(callback)[source]

此过滤器接受一个回调函数(该函数应该接受一个参数,即要记录的记录),并为通过过滤器的每个记录调用它。如果回调返回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[source]

此过滤器仅在 settings.DEBUG 为 False 时传递记录。

此过滤器在默认的 LOGGING 配置中按如下方式使用,以确保只有在 DEBUGFalse 时,AdminEmailHandler 才会向管理员发送错误邮件。

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[source]

此过滤器类似于 RequireDebugFalse,不同之处在于只有当 DEBUGTrue 时才传递记录。

返回顶部