一份日志配置由Loggers
、Handlers
、Filters
、Formatters
四部分组成。
Loggers
Logger
即记录器,是日志系统的入口。它有三个重要的工作:
- 向应用程序(也就是你的项目)公开几种方法,以便运行时记录消息
- 根据传递给Logger的消息的严重性,确定出需要处理的消息
- 将需要处理的消息传递给所有感兴趣的处理器(
Handler
)
每一条写入logger的消息都是一条日志记录。每一条日志记录也包含级别,代表对应消息的严重程度。常用的级别如下:
DEBUG
:排查故障时使用的低级别系统信息,通常开发时使用INFO
:一般的系统信息,并不算问题WARNING
:描述系统发生的小问题的信息,但通常不影响功能ERROR
:描述系统发生的大问题的信息,可能会导致功能不正常CRITICAL
:描述系统发生严重问题的信息,应用程序有崩溃风险
当logger处理一条消息时,会将自己的日志级别和这条消息的日志级别做对比。如果消息的级别匹配或者高于logger的日志级别,它就会被进一步处理;否则这条消息就会被忽略掉。
当logger确定了一条消息需要处理之后,会把它传给Handler
。
Handlers
Handler
即处理器,它的主要功能是决定如何处理logger中每一条消息,比如把消息输出到屏幕、文件或者Email中。
和logger一样,handler也有级别的概念。如果一条日志记录的级别不匹配或者低于handler的日志级别,则会被handler忽略。
一个logger可以有多个handler,每一个handler可以有不同的日志级别。这样就可以根据消息的重要性不同,来提供不同类型的输出。例如,你可以添加一个handler把ERROR
和CRITICAL
消息发到你的Email,再添加另一个 handler把所有的消息(包括ERROR
和CRITICAL
消息)保存到文件里。
Filters
Filter
即过滤器。在日志记录从logger传到handler的过程中,使用Filter
来做额外的控制。例如只允许某个特定来源的ERROR
消息输出。
Filter还被用来在日志输出之前对日志记录做修改。例如当满足一定条件时,把日志记录从 ERROR
降到 WARNING
级别。
Filter在logger和handler中都可以添加;多个filter可以链接起来使用,来做多重过滤操作。
Formatters
Formatter
即格式化器,主要功能是确定最终输出的形式和内容。
从最简单的开始
MyBlog/settings.py
...
import os
LOGGING = {
'version': 1,
'disable_existing_loggers': False,
'handlers': {
'file': {
'level': 'DEBUG',
'class': 'logging.FileHandler',
'filename': os.path.join(BASE_DIR, 'logs/debug.log'),
},
},
'loggers': {
'django': {
'handlers': ['file'],
'level': 'DEBUG',
'propagate': True,
},
},
}
上面的配置表示debug级别以上的日志被file这个处理器处理,存到MyBlog/logs/debug.log中
由于设置了debug级别,所以日志信息会很多
propagate': True
意思是本记录器处理过的消息其他处理器也可以继续处理
来个复杂的配置,详细解释看注释
EMAIL_HOST = 'smtp.qq.com'
EMAIL_PORT = 587
EMAIL_USE_TLS = True
EMAIL_HOST_USER = 'xxxxx@qq.com'
EMAIL_HOST_PASSWORD = 'xxxxx'
LOGGING = {
'version': 1,
'disable_existing_loggers': True,
'formatters': {
# 详细的格式化器,依次输出:消息级别、发生时间、抛出模块、进程ID、线程ID、提示信息
'verbose': {
'format': '{levelname} {asctime} {module} {process:d} {thread:d} {message}',
'style': '{',
},
# 简要的格式化器,仅输出消息级别和提示信息
'simple': {
'format': '{levelname} {message}',
'style': '{',
},
},
# 过滤器-仅在debug=True时生效
'filters': {
'require_debug_true': {
'()': 'django.utils.log.RequireDebugTrue',
},
},
# 处理器
'handlers': {
# 处理INFO以上级别消息,输出简要信息到命令行中;此处理器仅在调试模式生效
'console': {
'level': 'INFO',
'filters': ['require_debug_true'],
'class': 'logging.StreamHandler',
'formatter': 'simple'
},
# 处理ERROR以上级别消息,输出详细信息到Email中
'mail_admins': {
'level': 'ERROR',
'class': 'django.utils.log.AdminEmailHandler',
'include_html': False,
},
# 处理WARNING以上级别消息,输出详细信息到文件中
'file': {
'level': 'DEBUG',
'class': 'logging.FileHandler',
'filename': os.path.join(BASE_DIR, 'logs/debug.log'),
},
},
# django产生的所有消息转交给console处理器
# 将网络请求相关消息转交给file、mail_admins这两个处理器
'loggers': {
'django': {
'handlers': ['console'],
'level': 'DEBUG',
'propagate': True,
},
'django.request': {
'handlers': ['file', 'mail_admins'],
'level': 'DEBUG',
# 'propagate': False使得此记录器处理过的消息就不再让django记录器再次处理了
'propagate': False,
}
}
}