Python logging中Handler设为ERROR级别却输出Warning日志的问题
Python logging:Handler级别设为ERROR但Warning日志仍被打印的问题
问题现象:在logging中,日志级别低于Handler设置的级别却被记录。具体场景为:Handler设置为
logging.ERROR级别,但Warning日志仍被打印。代码示例:
import logging # root logger logging.basicConfig(level=logging.DEBUG) logging.root.addFilter(logging.Filter("root")) for handler in logging.root.handlers: handler.setLevel(level=logging.INFO) # my logger logger = logging.getLogger("myLog") logger.setLevel(logging.WARNING) handler1 = logging.StreamHandler() handler1.setLevel(logging.ERROR) logger.addHandler(handler1) # my logger log logger.debug("logger debug") logger.info("logger info") logger.warning("logger warning") # why logger.error("logger error") logger.critical("logger critical")输出结果:
WARNING:myLog:warning error ERROR:myLog:error critical CRITICAL:myLog:critical期望仅打印ERROR及以上级别的日志。
问题原因
问题出在Python logging的日志传播机制:
- 自定义logger默认会将日志消息向上传播给父级logger(这里
myLog的父级是root logger)。 - 虽然
handler1被设置为只处理ERROR及以上级别,但logger.warning("logger warning")会先通过myLog自身的级别过滤(符合设置的logging.WARNING级别),随后被传播到root logger。 - root logger的handler被设置为
logging.INFO级别,WARNING及以上日志会被root的handler打印,这就是输出中出现WARNING:myLog:warning的原因。
解决方案
给自定义logger添加logger.propagate = False配置,阻止日志传播到父级logger,这样只有自定义handler会处理日志。
修改后的代码
import logging # root logger logging.basicConfig(level=logging.DEBUG) logging.root.addFilter(logging.Filter("root")) for handler in logging.root.handlers: handler.setLevel(level=logging.INFO) # my logger logger = logging.getLogger("myLog") logger.setLevel(logging.WARNING) logger.propagate = False # 阻止日志传播到父级logger handler1 = logging.StreamHandler() handler1.setLevel(logging.ERROR) logger.addHandler(handler1) # my logger log logger.debug("logger debug") logger.info("logger info") logger.warning("logger warning") logger.error("logger error") logger.critical("logger critical")
修改后的输出
error critical
完全符合仅打印ERROR及以上级别的日志的预期。
内容的提问来源于stack exchange,提问作者xnningnanjing
相关产品推荐
相关产品推荐

