目录
logging配置方式:显式配置
import logging
import sys
def init_logging():
#创建日志记录器
logger = logging.getLogger()
# 日志器设置级别
logger.setLevel(logging.DEBUG)
# 创建处理器
severHandler = logging.StreamHandler(sys.stdout) # 控制台输出
# 处理器添加日志级别
severHandler.setLevel(logging.INFO)
severHandler.setFormatter(logging.Formatter('%(asctime)s |f %(levelname)s: %(message)s'))
# 添加处理器
logger.addHandler(severHandler)
if __name__ == '__main__':
init_logging()
logging.critical("这是严重错误level的日志")
logging.error("这是错误level的日志")
logging.warning("这是警告level的日志")
logging.info("这是信息level的日志")
logging.debug("这是调试信息level的日志")
输出结果如下:因为处理器日志级别为INFO,输出INFO及以上级别日志
添加过滤器之后代码如下:
class ChangeLogLevel(logging.Filter):
def filter(self, record):
return record.levelno > logging.WARNING
def init_logging():
#创建日志记录器
logger = logging.getLogger()
# 日志器设置级别
logger.setLevel(logging.DEBUG)
# 创建处理器
severHandler = logging.StreamHandler(sys.stdout) # 控制台输出
# 处理器添加日志级别
severHandler.setLevel(logging.INFO)
severHandler.setFormatter(logging.Formatter('%(asctime)s |f %(levelname)s: %(message)s'))
severHandler.addFilter(ChangeLogLevel())
# 添加处理器
logger.addHandler(severHandler)
输出结果如下: 过滤器过滤后仅记录高于WARN级别日志
logging配置方式:basicConfig
import logging
from logging.handlers import TimedRotatingFileHandler
import sys
class ChangeLogLevel(logging.Filter):
def filter(self, record):
return record.levelno > logging.WARNING
def use_basic_onfig():
timed_rotating_file_handler = TimedRotatingFileHandler('test.log',when='h',backupCount=3)
kw = {
'format':'%(asctime)s | %(levelname)s: %(message)s', # 这是给哪些没安排 formatter 的 handler 准备的
'datefmt' : '%Y-%m-%d %H:%M:%S',
'level': logging.INFO, # root logger 的 Level
'handlers': [timed_rotating_file_handler],
}
logging.basicConfig(**kw)
if __name__ == '__main__':
use_basic_onfig()
logging.critical("这是严重错误level的日志")
logging.error("这是错误level的日志")
logging.warning("这是警告level的日志")
logging.info("这是信息level的日志")
logging.debug("这是调试信息level的日志")
输出结果:
总结
1、logging四个组件:logger(日志记录器),handler(日志处理器),formatter(格式化器)、filter(日志过滤器)
一个项目中可以设置多个logger,logger = logging.getLogger('***'),每个logger定义不同的日志级别、处理器过滤器等,以便日志分类查询。Logger的默认level是WARNING=30
handler可以配置日志级别、日志格式化样式、日志过滤器等。Handler的默认level是NOSET=0
2、logging.getLogger(),不指定名称时会创建一个默认的RootLogger,如果没有单独配置日志记录器时日志使用RootLogger记录日志
3、日志先经过Logger的Level过滤再进入各handler处理,所以一般logger的level配置较低
错误的配置方式
方式一
如图中配置方式得到的运行结果为:
不了解logging机制时会有疑问:16行已经配置了level=INFO,为什么不能打印info日志??
原因就是18行已经生成了RootLogger的handler,那么19行basicConfig实际不产生作用了,即kw={}那些配置都是无效的,源码如下图:len(root.handlers) == 0时,才会使用kw参数设置RootLogger的level及handler。
方式二
将方式一的代码换一下顺序,输出结果如下:
此时已经很容易理解原因了:basicConfig先设置了RootLogger的level及默认handler,及handler的formatter。之后又设置了1个timed_rotating_file_handler。两个handler所以输出两次日志。timed_rotating_file_handler的level伟WARNING并且没有formatter,所以只输出3行日志,并且为原始样式。
参考文章:
https://www.jianshu.com/p/feb86c06c4f4
python 中的 logging 详解_python logging-CSDN博客
python - logging的四大组件(日志器、处理器、过滤器、格式器)_python logging模块 4大部分-CSDN博客