Django 官方文档地址 https://docs.djangoproject.com/en/2.0/topics/logging/#examples
Python dictConfig 的配置,参考 **Python ** 官方手册
https://docs.python.org/3/library/logging.config.html#logging-config-dictschema
本文针对 Django 配置日志输出、控制台日志全部输出到文件、日志/控制台 console 重定向到文件。
Django 利用的就是 Python 提供的 logging 模块,但 Django 中要用 logging,还得有一定的配置规则,需要在 settings.py 中设置。
默认情况下,Django 使用 dictConfig 格式。为了配置日志记录,您可以使用 LOGGING 定义日志记录设置的字典。这些设置描述了您希望在日志记录设置
中使用的日志记录器,处理程序,过滤器和格式化程序,以及希望这些组件具有的日志级别和其他属性。
如果将 dictConfig 中的 disable_existing_loggers 键 LOGGING 设置为 True(默认值),则将禁用默认配置中的所有记录器。禁用的记录器与已删除的记
录器不同;记录器仍将存在,但会静默丢弃记录到它的所有内容,甚至不会将条目传播到父记录器。因此,您应该非常小心地使用;这可能不是您想要的。相反,
您可以设置为并重新定义一些或所有默认记录器;或者您可以自定义设置。
配置如下:
disable_existing_loggers: True 禁用默认配置中的所有记录器
disable_existing_loggers: False 启动默认配置中的所有记录器
一个简单的文件日志配置,它将所有日志记录从 Django 记录器写入本地文件。
import os
LOGGING = {
'version': 1, # 定义版本 1
'disable_existing_loggers': False, # 允许使用已有的默认过滤器
'handlers': { # 日志处理器
'file': { # 定义一个处理器 file
'level': 'DEBUG', # 定义 handelr 的日志级别
'class': 'logging.FileHandler', # 使用文件类处理器,可以将日志写入文件中
'filename': '/path/to/django/debug.log', # 定义 DEBUG 日志信息的存储路径,文件路径需要确认有可写权限
},
},
'loggers': { # 日志记录器
'django': { # 记录 django 项目中的信息
'handlers': ['file'], # 使用处理器 file
'level': 'DEBUG', # 日志的等级为 DEBUG
'propagate': True, # 允许传播至上级记录器
},
},
}
字典中的 version 指明了配置的版本;disable_existing_loggers 指明是否禁止默认配置的记录器。(这两项通常不需要去改动)
重点看 loggers 和 handlers 的配置:
如前面说,一条消息首先传递给 logger。Django 中内置了几种记录器,比如这里用到的 Django 记录器,它会接收 Django 层次结构中的所有消息。
然后我们定义了需要处理 DEBUG 以上级别的消息,并把这些消息传递给名叫file的处理器。
‘propagate’: True 可以基于每个记录器控制该传播,如果您不希望特定记录器传播到其父项,则可以关闭此行为。
现在消息来到名叫 file 的 handlers 中了。这个处理器定义了消息处理级别仍然为 DEBUG,在 class 中定义将消息输出到文件中去,文件地址为项目目录的 /path/to/django/debug.log 。
因为这里没有配置 filters 和 formatters,因此会采用默认的设置。
需要注意的是日志的输出文件的目录 /path/to/django/ 一定要提前创建好,并且确保项目拥有此目录的写入权限。
默认情况下,此配置仅将日志等级为 INFO 的日志向 console 控制台发送消息,其他级别或更高级别的消息则不发送至控制台。
与 Django 的默认日志记录配置相同,但默认情况下仅在 DEBUG=True 时显示日志记录。
Django 不会记录许多此类消息。但是,通过此配置,您还可以设置环境变量 DJANGO_LOG_LEVEL=DEBUG 以查看 Django 的所有调试日志记录,这非常
冗长,因为它包含所有数据库查询。
import os
LOGGING = {
'version': 1, # 定义版本 1
'disable_existing_loggers': False, # 允许使用已有的默认过滤器
'handlers': { # 日志处理器
'console': { # 定义一个处理器 console
'class': 'logging.StreamHandler', # 使用流处理类,可以将信息打印到控制台
},
},
'loggers': { # 日志记录器
'django': { # 记录 django 项目中的信息
'handlers': ['console'], # 使用处理器 console
'level': os.getenv('DJANGO_LOG_LEVEL', 'INFO'), # 日志的等级为 INFO
},
},
}
所有与日志有关的配置默认在 LOGGING ={} 中,distConfig 格式。如果我们没有进行特别配置,Django 会执行默认的日志配置。
Django settings 默认配置:
DEBUG = True
django logger 及其(除 django.server 之外)所有下级的 INFO 以上的日志,都会被 StreamHandler 处理(输出到 console )
DEBUG = Flase
django logger 及其(除 django.server 之外)所有下级的 ERROR 和 CRITICAL 的日志,都会被 AdminEmailHandler 处理(发送至指定邮件)
如果我们不想使用默认的配置,可以将 LOGGING 中的 ‘disable_existing_loggers’ 设置为 True(默认也是 True ),这样一来,默认的配置就会被禁用。
但是设置 ‘disable_existing_loggers’: True,必须要非常小心,因为可能产生一些令人意外的结果(官网这么说的,还没试过),所以比较建议的方法
是 ‘disable_existing_loggers’: False,然后重写部分或者全部的默认 logger。
LOGGING = {
'version': 1, # 定义版本 1
'disable_existing_loggers': False, # 允许使用已有的默认过滤器
'formatters': { # 日志格式器
'verbose': { # 定义一个格式器 verbose
'format': '%(levelname)s %(asctime)s %(module)s %(process)d %(thread)d %(message)s'
# 输出日志级别名称,日志消息以及生成日志消息的时间,进程,线程和模块
},
'simple': { # 定义一个格式器 simple
'format': '%(levelname)s %(message)s' # 仅输出日志级别名称(例如 DEBUG)和日志消息
},
},
'filters': { # 日志过滤器
'special': { # 定义一个过滤器 sepcial
'()': 'project.logging.SpecialFilter',
'foo': 'bar',
},
'require_debug_true': {
'()': 'django.utils.log.RequireDebugTrue',
},
},
'handlers': { # 日志处理器
'console': { # 定义一个处理器 console,将 INFO 级别的日志使用 stream 流处理打印到控制台
'level': 'INFO',
'filters': ['require_debug_true'],
'class': 'logging.StreamHandler',
'formatter': 'simple' # 过滤规则使用 simple,只输出日志等级以及 messages 信息
},
'mail_admins': { # 定义一个处理器 mail_admis,将 ERROR 级别的日志使用 AdminEmailHandler 处理器
'level': 'ERROR',
'class': 'django.utils.log.AdminEmailHandler',
'filters': ['special'] # 将错误信息发送到该网站的 admin 超级用户的邮箱,错误信息格式采用 special 格式处理
}
},
'loggers': { # 日志记录器
'django': { # 定义一个记录器 django,使用 console 处理器,即将记录的信息打印到控制台
'handlers': ['console'],
'propagate': True, # 允许传播至上级记录器
},
'django.request': { # 定义一个记录器 django.request,使用 main_admins 处理器,只处理邮件发送的错误信息
'handlers': ['mail_admins'],
'level': 'ERROR',
'propagate': False, # 禁用传播至上级记录器 django
},
'myproject.custom': { # 定义一个记录器 myproject.custome,同时使用 console、mail_admis 处理器
'handlers': ['console', 'mail_admins'],
'level': 'INFO',
'filters': ['special']
}
}
}
将配置文件的格式标识为 “ 版本1 ” 格式。也是目前唯一的版本格式。
定义两个格式化程序:
simple
仅输出日志级别名称(例如 DEBUG )和日志消息。
该 format 字符串是普通的 Python 格式化字符串,描述了将在每条记录行上输出的详细信息。
可以输出的详细信息的完整列表可以在 Formatter Objects 中找到。
verbose
输出日志级别名称,日志消息以及生成日志消息的时间,进程,线程和模块。
定义两个过滤器:
project.logging.SpecialFilter (special)
如果此过滤器需要其他参数,则可以在过滤器配置字典中将它们作为其他关键字提供,在这种情况下,实例化时 foo 将为参数提供值。
django.utils.log.RequireDebugTrue
该记录在 DEBUG is True 时传递。
定义两个处理程序:
console,StreamHandler
将任何 INFO (或更高版本的)消息打印到 sys.stderr。该处理程序使用 simple 输出格式。
mail_admins,AdminEmailHandler
通过电子邮件将任何 ERROR (或更高版本)消息发送到该网站 ADMINS。该处理程序使用 special 过滤器。
配置三个记录器:
django
将所有消息传递给 console 处理程序。
django.request
将所有 ERROR 消息传递给 mail_admins 处理程序。另外,该记录器被标记为不传播消息。
这意味着记录器 django.request 将不会处理写入日志消息至 django。
myproject.custom
将所有 INFO 或更高级别的消息传递给该消息,也将 special 过滤器传递给两个处理程序 console 和 mail_admins。
这意味着所有 INFO 级别的消息(或更高级别的消息)将被打印到控制台。ERROR 和 CRITICAL 消息也将通过电子邮件输出。
上面的日志配置提到需要在日志中发送错误信息至 admin 的邮箱,Django 项目中需要在 settings 配置好邮件发送的相关配置
'The email address that error messages come from, such as those sent to ADMINS and MANAGERS.'
# 邮件配置
EMAIL_HOST = 'smtp.maildomain.com' # SMTP地址
EMAIL_PORT = 25 # SMTP端口
EMAIL_HOST_USER = 'sender@maildomain.com' # 发送邮件的邮箱
EMAIL_HOST_PASSWORD = '******' # 我的邮箱密码
EMAIL_SUBJECT_PREFIX = u'[prefix]' # 为邮件 Subject-line 前缀,默认是 '[django]'
EMAIL_USE_TLS = True # 与 SMTP 服务器通信时,是否启动 TLS 链接(安全链接),默认 false
# 管理员站点
SERVER_EMAIL = 'adminli@163.com'
ADMINS = (('receiver', 'receiver@maildomain.com'),) # 接收邮件的邮箱(或邮件组)
如果您不想使用 Python 的 dictConfig 格式配置记录器,则可以指定自己的配置方案。
该 LOGGING_CONFIG 设置定义了用于配置 Django 记录器的可调用对象。默认情况下,它指向 Python 的 logging.config.dictConfig() 函数。但是,如果
要使用其他配置过程,则可以使用带有单个参数的任何其他可调用对象。LOGGING 配置日志记录时,将提供的内容作为该参数的值。
设置 LOGGING_CONFIG 为 None 仅表示禁用自动配置过程。如果禁用配置过程,Django 仍将进行日志记录调用,而回退到定义的默认日志记录行为。
在 settings 配置如下:
LOGGING_CONFIG = None
import logging.config
logging.config.dictConfig(...)
django 只是一个最上级的 logger,但实际上并不接收什么实际的信息,所有的信息都是通过下级 logger 接收。
处理请求处理有关的日志消息
发送给该记录器的消息具有以下额外的上下文:
runserver 命令调用的服务器接收的请求处理相关的日志消息
发送给该记录器的消息具有以下额外的上下文:
记录与模板渲染有关的消息
缺少的上下文变量将记录为 DEBUG 消息。
在调试模式关闭时,在关闭期间引发的未捕获异常将会记录为消息(这是有用的,因为在这种情况下使异常屏蔽并返回空字符串)。
{%include %} WARNING {% include %}
与代码与数据库的交互有关的消息
发送给该记录器的消息具有以下额外的上下文:
出于性能方面的考虑,仅在 settings.DEBUG 将 SQL 日志记录设置为 True 才启用 SQL 日志记录,而不考虑日志记录级别或已安装的处理程序。
此日志记录不包括框架级初始化(例如:SET TIMEZONE )或事务管理查询(例如:**SET TIMEZONE BEGIN COMMIT ROLLBACK **)。
如果要查看所有数据库查询,请打开数据库中的查询日志记录。
class AdminEmailHandler(include_html=False, email_backend=None)[source]
Django 除了提供 Python 日志记录 loggging 模块所提供的日志处理程序外,还提供了一个特别的日志处理程序。
该处理程序 ADMINS 针对收到的每个日志消息都会向该站点 admin 用户发送一封电子邮件。
如果日志记录包含 request 属性,则请求的完整详细信息将包含在电子邮件中。
如果客户的 IP 地址在 INTERNAL_IPS 设置中,则电子邮件主题将包含短语“内部 IP” ;如果没有,它将包括 “EXTERNAL IP”。
如果日志记录包含堆栈跟踪信息,则该堆栈跟踪将包含在电子邮件中。
'handlers': {
'mail_admins': {
'level': 'ERROR',
'class': 'django.utils.log.AdminEmailHandler',
# 设置为 True 则包含 HTML 附件
'include_html': True,
}
},
注意
此电子邮件的 HTML 版本包含完整的追溯,在堆栈的每个级别上都包含局部变量的名称和值,以及 Django 设置的值。
所以此信息可能非常敏感,您可能不想通过电子邮件发送它。考虑使用诸如 Sentry 之类的东西来获得两全其美的体验。既有全面的回溯的丰富信息以及不通
过电子邮件发送信息的安全性。
您还可以明确指定要从错误报告中过滤掉的某些敏感信息,可以了解有关过滤错误报告的更多信息 。
通过设置 email_backend 的参数 AdminEmailHandler,可以覆盖处理程序正在使用的电子邮件后端,如下所示:
'handlers': {
'mail_admins': {
'level': 'ERROR',
'class': 'django.utils.log.AdminEmailHandler',
'email_backend': 'django.core.mail.backends.filebased.EmailBackend',
}
},
默认情况下,EMAIL_BACKEND 将使用指定的电子邮件
send_mail(subject,message,*args,**kwargs)[源代码]**
向管理员用户发送电子邮件。若要自定义此行为,可以对 AdminEmailHandler 类进行子类化并重写此方法。
Django 除了提供 Python 日志记录模块所提供的日志过滤器外,还提供了一些特别日志过滤器。
classCallbackFilter(callback)source
示例
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
'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 配置,以确保 AdminEmailHandler 当只发送错误电子邮件到管理员:
'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]
这个过滤器 filter 类似于 RequireDebugFalse ,只有当 settings.DEBUG 为 True 的时候,才会被调用。