logging模块处理流程:
分为几个模块:
- logger: 最高层模块,用来输出log
- logger.level来筛选log
- logger.debug()/info()/warning()/error()等输出log
- handler: 经过logger过滤后log会分发给所有handler处理。每个handler有自己的level, formatter, 以及输出流
- handler.level 过滤log
- handler.formatter 决定log输出的样式
StreamHandler: 常见的StreamHandler输出到标准流,FileHandler,输出到文件
level的排序:NOTSET < DEBUG < INFO < WARNING < ERROR
只有大于level的才会被处理
注意:一条log会经历两次过滤,一次是logger.level,一次是handler.level,被前者过滤掉的log不会进入handler处理流程。handler的level和logger的level没有什么必然关系。
e.g. 1. 最基本的使用方法:
import logging
logging.info('这条不会输出,因为默认level是WARNING')
logging.warning('这条会输出')
默认会输出到stderr
e.g. 2. 带自定义输出的基本使用方法:
import logging, sys
if __name__ == '__main__':
logger = logging.getLogger(__name__)
logging.basicConfig(
format="%(asctime)s - %(levelname)s - %(name)s - %(message)s",
datefmt="%m/%d/%Y %H:%M:%S",
handlers=[logging.StreamHandler(sys.stdout), logging.FileHandler('output.log')],
)
logger.setLevel(logging.INFO)
logger.info('hello world')
输出如下:
09/18/2022 21:50:53 - INFO - __main__ - hello world
同时会输出到文件output.log
一些重要的默认值
- 默认有一个root logger,是自己定义的logger的parent
- root的level默认是WARNING,无handler
- logger 所有parent直到root都没有handler时使用一个默认的全局handler,该handler的level是WARNING,输出到stderr
- 如果logger没定义level,会使用第一个找到的parent的非0(NOTSET)的level,一般是root的level (WARNING),如果所有parent都没有level,则使用NOTSET(最低级)
- basicConfig函数配置root logger的一些属性,如果root有handler,则basicConfig不起作用
- 手动创建的handler默认level是NOTSET,手动创建的logger默认level也是NOTSET,但是如果parent有非NOTSET的level,则优先使用parent的level(比如root的WARNING)
上文的e.g.2就是给root handler配置了两个handler,一个输出到stdout,一个输出到文件, 两个共用一个formatter,自己定义的logger是没有handler的,最终递归地使用了root的handler
e.g.3 INFO和WARNING分开输出到不同的地方
import logging
from sys import stdout, stderr
if __name__ == "__main__":
format="%(asctime)s - %(levelname)s - %(name)s - %(message)s"
datefmt="%m/%d/%Y %H:%M:%S"
formatter = logging.Formatter(format, datefmt, '%')
# logger to stdout
logger = logging.getLogger(__name__)
# 不能设置成NOTSET,不然优先使用root的level,即warning
logger.setLevel(logging.DEBUG)
hdlr = logging.StreamHandler(stdout)
hdlr.setFormatter(formatter)
logger.addHandler(hdlr)
# logger to stderr
err = logging.getLogger(__name__ + 'err')
err.setLevel(logging.WARNING)
hdlr = logging.StreamHandler(stderr)
hdlr.setFormatter(formatter)
err.addHandler(hdlr)
标签:__,logging,log,level,python,handler,模块,logger
From: https://www.cnblogs.com/wangbingbing/p/16706005.html