如何配置和使用日志

Django 提供了一个可随时扩展的默认日志记录配置

进行基本的日志记录调用

要从代码中发送日志消息,请在其中放置一个日志记录调用。

不要试图在settings.py中使用日志记录调用。

Django 日志记录在 setup() 函数中配置的方式意味着放置在 settings.py 中的日志记录调用可能无法按预期工作,因为此时日志记录尚未设置。要探索日志记录,请使用如下示例中建议的视图函数。

首先,导入 Python 日志记录库,然后使用logging.getLogger()获取日志记录器实例。为 getLogger() 方法提供一个名称来标识它及其发出的记录。一个不错的选择是使用 __name__(有关此方面的更多信息,请参见下面的使用日志记录器命名空间),它将提供当前 Python 模块的名称作为点分路径

import logging

logger = logging.getLogger(__name__)

这是一个良好的约定,可以在模块级别执行此声明。

然后在函数中,例如在视图中,向日志记录器发送记录

def some_view(request):
    ...
    if some_risky_state:
        logger.warning("Platform is running at risk")

执行此代码时,将向日志记录器发送包含该消息的LogRecord。如果使用 Django 的默认日志记录配置,则该消息将显示在控制台中。

上面示例中使用的 WARNING 级别是多个日志记录严重级别之一:DEBUGINFOWARNINGERRORCRITICAL。因此,另一个示例可能是

logger.critical("Payment system is not responding")

重要

默认情况下,级别低于 WARNING 的记录不会显示在控制台中。更改此行为需要其他配置。

自定义日志记录配置

尽管 Django 的日志记录配置可以开箱即用,但您可以通过一些其他配置来精确控制日志如何发送到各种目标 - 发送到日志文件、外部服务、电子邮件等。

您可以配置

  • 日志记录器映射,以确定哪些记录发送到哪些处理程序

  • 处理程序,以确定它们如何处理接收到的记录

  • 过滤器,以提供对记录传输的额外控制,甚至修改记录

  • 格式化程序,将LogRecord对象转换为字符串或其他形式,以便人类或其他系统使用

有多种配置日志记录的方法。在 Django 中,最常使用LOGGING设置。该设置使用dictConfig 格式,并扩展了默认日志记录配置

有关自定义设置如何与 Django 的默认设置合并的说明,请参阅配置日志记录

有关其他配置日志记录方法的详细信息,请参阅Python logging documentation。为简单起见,本文档仅考虑通过 LOGGING 设置进行配置。

基本日志记录配置

配置日志记录时,有必要

创建LOGGING字典

在您的settings.py

LOGGING = {
    "version": 1,  # the dictConfig format version
    "disable_existing_loggers": False,  # retain the default loggers
}

disable_existing_loggers 设置为 False,几乎总是可以保留并扩展默认日志记录配置。

配置处理程序

此示例配置了一个名为 file 的单个处理程序,它使用 Python 的FileHandler将级别为 DEBUG 及更高的日志保存到文件 general.log(位于项目根目录)

LOGGING = {
    # ...
    "handlers": {
        "file": {
            "class": "logging.FileHandler",
            "filename": "general.log",
        },
    },
}

不同的处理程序类采用不同的配置选项。有关可用处理程序类的更多信息,请参阅 Django 提供的AdminEmailHandler以及 Python 提供的各种handler classes

还可以对处理程序设置日志记录级别(默认情况下,它们接受所有级别的日志消息)。使用上面的示例,添加

{
    "class": "logging.FileHandler",
    "filename": "general.log",
    "level": "DEBUG",
}

将定义一个仅接受级别为 DEBUG 及更高的记录的处理程序配置。

配置日志记录器映射

要将记录发送到此处理程序,请配置日志记录器映射以使用它,例如

LOGGING = {
    # ...
    "loggers": {
        "": {
            "level": "DEBUG",
            "handlers": ["file"],
        },
    },
}

映射的名称确定它将处理哪些日志记录。此配置('')是未命名的。这意味着它将处理来自所有日志记录器的记录(有关如何使用映射名称确定它将为其处理记录的日志记录器的更多信息,请参见下面的使用日志记录器命名空间)。

它将把级别为 DEBUG 及更高的消息转发到名为 file 的处理程序。

请注意,日志记录器可以将消息转发到多个处理程序,因此日志记录器和处理程序之间的关系是多对多的。

如果执行

logger.debug("Attempting to connect to API")

在您的代码中,您将在项目根目录下的文件 general.log 中找到该消息。

配置格式化程序

默认情况下,最终的日志输出包含每个log record的消息部分。如果要包含其他数据,请使用格式化程序。首先命名和定义您的格式化程序 - 此示例定义了名为 verbosesimple 的格式化程序

LOGGING = {
    # ...
    "formatters": {
        "verbose": {
            "format": "{name} {levelname} {asctime} {module} {process:d} {thread:d} {message}",
            "style": "{",
        },
        "simple": {
            "format": "{levelname} {message}",
            "style": "{",
        },
    },
}

style 关键字允许您为str.format()指定 { 或为string.Template格式化指定 $;默认值为 $

有关可以包含的LogRecord 属性,请参阅LogRecord属性。

要将格式化程序应用于处理程序,请向处理程序的字典中添加一个 formatter 条目,并通过名称引用格式化程序,例如

"handlers": {
    "file": {
        "class": "logging.FileHandler",
        "filename": "general.log",
        "formatter": "verbose",
    },
}

使用日志记录器命名空间

未命名的日志记录配置 '' 会捕获来自任何 Python 应用程序的日志。命名日志记录配置将仅捕获来自名称匹配的日志记录器的日志。

日志记录器实例的命名空间是使用getLogger()定义的。例如,在 my_appviews.py

logger = logging.getLogger(__name__)

将在 my_app.views 命名空间中创建一个日志记录器。 __name__ 允许您根据日志消息在其项目应用程序中的来源自动对其进行组织。它还确保您不会遇到名称冲突。

名为 my_app.views 的日志记录器映射将捕获来自此日志记录器的记录。

LOGGING = {
    # ...
    "loggers": {
        "my_app.views": {...},
    },
}

名为 my_app 的日志记录器映射将更宽松,捕获来自 my_app 命名空间中任何位置的日志记录器的记录(包括 my_app.viewsmy_app.utils 等)。

LOGGING = {
    # ...
    "loggers": {
        "my_app": {...},
    },
}

您还可以显式定义日志记录器命名空间。

logger = logging.getLogger("project.payment")

并相应地设置日志记录器映射。

使用日志记录器层次结构和传播

日志记录器命名是分层的my_appmy_app.views 的父级,后者是 my_app.views.private 的父级。除非另有说明,否则日志记录器映射会将其处理的记录传播到其父级 - 来自 my_app.views.private 命名空间中日志记录器的记录将由 my_appmy_app.views 的映射处理。

要管理此行为,请在您定义的映射上设置传播键。

LOGGING = {
    # ...
    "loggers": {
        "my_app": {
            # ...
        },
        "my_app.views": {
            # ...
        },
        "my_app.views.private": {
            # ...
            "propagate": False,
        },
    },
}

propagate 默认为 True。在此示例中,来自 my_app.views.private 的日志不会由父级处理,但来自 my_app.views 的日志会。

配置响应式日志记录

当日志包含尽可能多的信息时,日志记录最有帮助,但不要包含您不需要的信息 - 以及您需要多少信息取决于您正在做什么。当您进行调试时,您需要的信息级别在生产环境中会过量且无用。

您可以配置日志记录以在您需要时为您提供所需的信息级别。与其手动更改配置以实现此目的,更好的方法是根据环境自动应用配置。

例如,您可以在开发和暂存环境中适当地设置环境变量 DJANGO_LOG_LEVEL,并在日志记录器映射中使用它,如下所示

"level": os.getenv("DJANGO_LOG_LEVEL", "WARNING")

- 因此,除非环境指定了更低的日志级别,否则此配置只会将严重性为 WARNING 及以上的记录转发到其处理程序。

配置中的其他选项(例如处理程序的 levelformatter 选项)可以类似地进行管理。

返回顶部