登录

参见

Python程序员将经常使用 print() 在他们的代码中作为一种快速方便的调试工具。使用日志记录框架的工作量只比这多一点,但它要优雅和灵活得多。除了对调试有用之外,日志记录还可以为您提供有关应用程序状态和运行状况的更多、结构更好的信息。

概述

Django使用并扩展了Python的内置 logging 模块来执行系统日志记录。本模块在Python自己的文档中进行了详细讨论;本节提供了一个快速概述。

演员阵容

python日志配置由四部分组成:

Loggers

A logger 是进入日志系统的入口点。每个记录器都是一个命名的存储桶,可以将消息写入其中进行处理。

记录器配置为具有 日志级别 . 此日志级别描述记录器将处理的消息的严重性。python定义了以下日志级别:

  • DEBUG :用于调试的低级系统信息

  • INFO :一般系统信息

  • WARNING :描述发生的小问题的信息。

  • ERROR :描述发生的主要问题的信息。

  • CRITICAL :描述发生的关键问题的信息。

写入日志程序的每条消息都是 日志记录 . 每个日志记录还具有 日志级别 指示该特定消息的严重性。日志记录还可以包含描述正在记录的事件的有用元数据。这可以包括堆栈跟踪或错误代码等详细信息。

向记录器提供消息时,将消息的日志级别与记录器的日志级别进行比较。如果消息的日志级别满足或超过记录器本身的日志级别,则消息将进行进一步处理。否则,消息将被忽略。

一旦记录器确定需要处理消息,它就会传递给 处理程序 .

处理程序

这个 handler 是确定记录器中的每条消息发生了什么情况的引擎。它描述了特定的日志记录行为,例如将消息写入屏幕、文件或网络套接字。

和记录器一样,处理程序也具有日志级别。如果日志记录的日志级别不满足或超过处理程序的级别,处理程序将忽略该消息。

日志记录器可以有多个处理程序,每个处理程序可以有不同的日志级别。通过这种方式,可以根据消息的重要性提供不同形式的通知。例如,您可以安装一个处理程序来转发 ERRORCRITICAL 向分页服务发送消息,而第二个处理程序记录所有消息(包括 ERRORCRITICAL 消息)发送到一个文件以供以后分析。

过滤器

A filter 用于提供对哪些日志记录从记录器传递到处理程序的额外控制。

默认情况下,将处理满足日志级别要求的任何日志消息。但是,通过安装过滤器,您可以在日志记录过程中放置其他条件。例如,您可以安装一个只允许 ERROR 要从特定源发出的消息。

过滤器也可用于在发出日志记录之前修改日志记录。例如,您可以编写一个降级的过滤器 ERROR 日志记录到 WARNING 记录是否满足特定条件集。

过滤器可以安装在记录器或处理程序上;多个过滤器可以在一个链中用于执行多个过滤操作。

使用格式器

最终,需要将日志记录呈现为文本。 Formatters 请描述该文本的确切格式。格式化程序通常由包含以下内容的Python格式化字符串组成 LogRecord attributes ;但是,您也可以编写自定义格式化程序来实现特定的格式化行为。

对安全的影响

日志记录系统处理潜在的敏感信息。例如,日志记录可能包含有关Web请求或堆栈跟踪的信息,而您在自己的记录器中收集的某些数据也可能具有安全隐患。您需要确保您知道:

  • 收集了哪些信息

  • 随后它将被存储在哪里

  • 它将如何转移

  • 可能有权接触到它的人。

为了帮助控制敏感信息的收集,您可以显式指定要从错误报告中筛选出的某些敏感信息--阅读有关如何 filter error reports

AdminEmailHandler

内置的 AdminEmailHandler 在安全方面值得一提的是。如果它的 include_html 选项,则它发送的电子邮件将包含完整的回溯,在堆栈的每一级带有局部变量的名称和值,以及Django设置的值(换句话说,与在网页中显示的细节级别相同 DEBUGTrue )。

通过电子邮件发送这种潜在的敏感信息通常被认为不是一个好主意。取而代之的是,可以考虑使用许多第三方服务中的一种,可以将详细日志发送到这些服务,以充分利用这些服务--完整回溯的丰富信息、清楚地管理哪些人收到通知并有权访问这些信息,等等。

配置日志记录

python的日志库提供了几种配置日志的技术,从编程接口到配置文件。默认情况下,Django使用 dictConfig format .

为了配置日志记录,您可以使用 LOGGING 若要定义日志记录设置的词典,请执行以下操作。这些设置描述了您希望在日志记录设置中使用的记录器、处理程序、筛选器和格式化程序,以及您希望这些组件具有的日志级别和其他属性。

默认情况下, LOGGING 设置与合并 Django's default logging configuration 使用以下方案。

如果 disable_existing_loggers 关键在 LOGGING dictconfig设置为 True (哪个是 dictConfig 如果缺少键,则默认配置中的所有记录器都将被禁用。已禁用的记录器与已删除的记录器不同;记录器仍将存在,但将以静默方式丢弃记录到其中的任何内容,甚至不会将条目传播到父记录器。因此,您应该非常小心地使用 'disable_existing_loggers': True 可能不是你想要的。相反,你可以设置 disable_existing_loggersFalse 并重新定义部分或全部默认记录器;或者您可以设置 LOGGING_CONFIGNonehandle logging config yourself .

日志记录被配置为通用Django的一部分 setup() 功能。因此,您可以确定记录器总是可以在项目代码中使用。

实例

完整的文档 dictConfig format 是有关日志配置字典的最佳信息源。但是,为了让您了解可能的情况,这里有几个例子。

首先,这里有一个小配置,允许您将所有日志消息输出到控制台:

settings.py
import os

LOGGING = {
    "version": 1,
    "disable_existing_loggers": False,
    "handlers": {
        "console": {
            "class": "logging.StreamHandler",
        },
    },
    "root": {
        "handlers": ["console"],
        "level": "WARNING",
    },
}

这将配置父级 root 记录器发送消息 WARNING 控制台处理程序的级别和更高级别。通过调整水平 INFODEBUG 您可以显示更多消息。这在开发过程中可能有用。

接下来,我们可以添加更细粒度的日志记录。下面是一个示例,说明如何让日志系统从 django 命名记录器:

settings.py
import os

LOGGING = {
    "version": 1,
    "disable_existing_loggers": False,
    "handlers": {
        "console": {
            "class": "logging.StreamHandler",
        },
    },
    "root": {
        "handlers": ["console"],
        "level": "WARNING",
    },
    "loggers": {
        "django": {
            "handlers": ["console"],
            "level": os.getenv("DJANGO_LOG_LEVEL", "INFO"),
            "propagate": False,
        },
    },
}

默认情况下,此配置从 django 水准仪 INFO 或更高的控制台。这与Django的默认日志配置级别相同,只是默认配置只在以下情况下显示日志记录: DEBUG=True . Django并没有记录很多这样的记录 INFO 级别消息。但是,通过这个配置,您还可以设置环境变量 DJANGO_LOG_LEVEL=DEBUG 查看Django的所有调试日志,这是非常详细的,因为它包括所有数据库查询。

你不必登录控制台。下面是一个配置,它从 django 命名记录器到本地文件:

settings.py
LOGGING = {
    "version": 1,
    "disable_existing_loggers": False,
    "handlers": {
        "file": {
            "level": "DEBUG",
            "class": "logging.FileHandler",
            "filename": "/path/to/django/debug.log",
        },
    },
    "loggers": {
        "django": {
            "handlers": ["file"],
            "level": "DEBUG",
            "propagate": True,
        },
    },
}

如果使用此示例,请确保更改 'filename' 运行django应用程序的用户可写位置的路径。

最后,下面是一个相当复杂的日志设置示例:

settings.py
LOGGING = {
    "version": 1,
    "disable_existing_loggers": False,
    "formatters": {
        "verbose": {
            "format": "{levelname} {asctime} {module} {process:d} {thread:d} {message}",
            "style": "{",
        },
        "simple": {
            "format": "{levelname} {message}",
            "style": "{",
        },
    },
    "filters": {
        "special": {
            "()": "project.logging.SpecialFilter",
            "foo": "bar",
        },
        "require_debug_true": {
            "()": "django.utils.log.RequireDebugTrue",
        },
    },
    "handlers": {
        "console": {
            "level": "INFO",
            "filters": ["require_debug_true"],
            "class": "logging.StreamHandler",
            "formatter": "simple",
        },
        "mail_admins": {
            "level": "ERROR",
            "class": "django.utils.log.AdminEmailHandler",
            "filters": ["special"],
        },
    },
    "loggers": {
        "django": {
            "handlers": ["console"],
            "propagate": True,
        },
        "django.request": {
            "handlers": ["mail_admins"],
            "level": "ERROR",
            "propagate": False,
        },
        "myproject.custom": {
            "handlers": ["console", "mail_admins"],
            "level": "INFO",
            "filters": ["special"],
        },
    },
}

此日志配置执行以下操作:

  • 将配置标识为“dictconfig version 1”格式。目前,这是唯一的dictconfig格式版本。

  • 定义两个格式化程序:

    • simple ,输出日志级别名称(例如。, DEBUG )以及日志消息。

      这个 format 字符串是一个普通的python格式字符串,描述将在每条日志记录行上输出的详细信息。可以输出的完整详细信息列表可以在 Formatter Objects .

    • verbose 输出日志级别名称、日志消息以及生成日志消息的时间、进程、线程和模块。

  • 定义两个筛选器:

    • project.logging.SpecialFilter ,使用别名 special . 如果此筛选器需要其他参数,则可以在筛选器配置字典中作为其他键提供这些参数。在这种情况下,论点 foo 将得到一个值 bar 实例化时 SpecialFilter .

    • django.utils.log.RequireDebugTrue ,当 DEBUGTrue .

  • 定义两个处理程序:

    • console ,A StreamHandler ,打印任何 INFO (或更高)消息发送至 sys.stderr . 此处理程序使用 simple 输出格式。

    • mail_admins ,一个 AdminEmailHandler ,它向任何人发送电子邮件 ERROR (或更高级别)发送到站点的消息 ADMINS 。此处理程序使用 special 过滤。

  • 配置三个记录器:

    • django ,它将所有消息传递给 console 处理程序。

    • django.request ,全部通过 ERROR 消息到 mail_admins 处理程序。此外,此记录器标记为 not 传播消息。这意味着日志消息被写入 django.request 不会由 django 记录器。

    • myproject.custom ,它在传递所有消息 INFO 或更高,也通过 special 过滤到两个处理程序-- consolemail_admins . 这意味着所有 INFO 级别信息(或更高级别)将打印到控制台; ERRORCRITICAL 邮件也将通过电子邮件输出。

自定义日志记录配置

如果不想使用python的dictconfig格式配置记录器,可以指定自己的配置方案。

这个 LOGGING_CONFIG 设置定义将用于配置Django的记录器的可调用文件。默认情况下,它指向python的 logging.config.dictConfig() 功能。但是,如果您想使用不同的配置过程,可以使用任何其他接受单个参数的可调用程序。内容 LOGGING 将在配置日志记录时作为该参数的值提供。

禁用日志配置

如果您根本不想配置日志记录(或者您想使用自己的方法手动配置日志记录),可以设置 LOGGING_CONFIGNone . 这将禁用的配置过程 Django's default logging .

设置 LOGGING_CONFIGNone 只意味着自动配置过程被禁用,而不是日志记录本身。如果禁用配置过程,Django仍将进行日志记录调用,返回到定义的默认日志记录行为。

下面是一个禁用Django日志记录配置,然后手动配置日志记录的示例:

settings.py
LOGGING_CONFIG = None

import logging.config

logging.config.dictConfig(...)

注意,默认配置过程只调用 LOGGING_CONFIG 设置完全加载后。相反,在设置文件中手动配置日志将立即加载日志配置。因此,必须显示日志记录配置 之后 它所依赖的任何设置。