Python日志默认设为INFO后,切换至DEBUG无法输出调试信息
日志级别修改后无法显示DEBUG信息的问题
现象说明
默认级别为DEBUG时(原配置)
运行正常,可随时切换日志级别:
>>> import mylog >>> log1 = mylog.mylogger('log1',level=10) # default is DEBUG added logger log1 of level:10 >>> log1 <Logger log1 (DEBUG)> >>> log1.debug("works") 20241007163742.800|DEBUG|<stdin>:1|works >>> log1.setLevel(20) >>> log1 <Logger log1 (INFO)> >>> log1.info("works") 20241007163825.042|INFO|<stdin>:1|works >>> log1.debug("should not show") >>>
切回DEBUG也正常:
>>> log1.setLevel(10) >>> log1 <Logger log1 (DEBUG)> >>> log1.debug("works") 20241007164010.113|DEBUG|<stdin>:1|works
默认级别改为INFO后
调用setLevel(10)修改日志级别为DEBUG后,无法显示DEBUG信息:
>>> log2 = mylog.mylogger('log2',level=20) # default is INFO added logger log2 of level:20 >>> log2 <Logger log2 (INFO)> >>> log2.info("works") 20241007164505.921|INFO|<stdin>:1|works >>> log2.debug("should not show") >>> log2.setLevel(10) >>> log2 <Logger log2 (DEBUG)> >>> log2.info("works as before") 20241007164628.199|INFO|<stdin>:1|works as before >>> log2.debug("why is this not showing") >>>
日志模块代码(mylog.py)
import logging def mylogger(name:str, level:int=logging.INFO) -> logging.Logger: """ default logger """ logger = logging.getLogger(name) if logger.hasHandlers(): print(f"logger {name} already has handler") else: logger.setLevel(level) console_fmt = "%(asctime)s.%(msecs)03d|%(levelname)s|%(pathname)s:%(lineno)d|%(message)s" datefmt = "%Y%m%d%H%M%S" ch = logging.StreamHandler() ch.setLevel(level) ch.setFormatter(logging.Formatter(console_fmt, datefmt)) # 注:原代码写为file_fmt,属于笔误 logger.addHandler(ch) logger.propagate = False print(f"added logger {name} of level:{logger.level}") return logger
问题原因
确实是StreamHandler的级别问题。创建StreamHandler时,你调用了ch.setLevel(level),默认把handler的级别设为INFO(20)。后续修改log2.setLevel(10)仅调整了logger本身的级别,但handler的级别仍为INFO,DEBUG级别的日志会被handler过滤,因此无法输出。
解决方法
有两种可行方案:
- 固定handler最低级别:把handler的级别设为
logging.DEBUG,让logger的级别控制输出。修改代码中ch.setLevel(level)为ch.setLevel(logging.DEBUG)。 - 同步修改logger与handler级别:如果需要动态调整handler级别,在修改logger级别时遍历其所有handler同步更新:
使用时调用def set_logger_level(logger, level): logger.setLevel(level) for handler in logger.handlers: handler.setLevel(level)set_logger_level(log2, logging.DEBUG)即可。
检查StreamHandler级别的方法
遍历目标logger的handlers属性,打印每个handler的级别:
>>> log2 = mylog.mylogger('log2', level=20) added logger log2 of level:20 >>> for handler in log2.handlers: ... print(f"Handler level: {handler.level}, type: {handler.__class__.__name__}") ... Handler level: 20, type: StreamHandler >>> log2.setLevel(10) >>> for handler in log2.handlers: ... print(f"Handler level: {handler.level}, type: {handler.__class__.__name__}") ... Handler level: 20, type: StreamHandler # 可见handler级别未随logger修改
内容的提问来源于stack exchange,提问作者MortenB
相关产品推荐
相关产品推荐

