You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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过滤,因此无法输出。

解决方法

有两种可行方案:

  1. 固定handler最低级别:把handler的级别设为logging.DEBUG,让logger的级别控制输出。修改代码中ch.setLevel(level)为ch.setLevel(logging.DEBUG)。
  2. 同步修改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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.17 14:40:04