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

Python 3.10中Logger无法输出INFO级别日志问题咨询

Python日志配置问题:INFO级别日志无法输出的解决办法

我用以下代码配置Python日志,但无论is_debug和is_interactive设为True还是False,INFO级别日志始终无法打印,即使日志处理器(handler)已设置为INFO级别:

import logging

# Define the setup_logger function (similar to the one you provided)
def setup_logger(dtc_name, log_dir, is_debug=False, is_interactive=False):
    formatter = logging.Formatter("%(asctime)s %(process)s %(levelname)s - %(message)s")

    logger = logging.getLogger(dtc_name)
    if logger.handlers:
        for handler in logger.handlers[:]:
            logger.removeHandler(handler)

    info_log = logging.FileHandler(f"{log_dir}/{dtc_name}.log")
    info_log.setFormatter(formatter)
    info_log.setLevel(logging.INFO)
    logger.addHandler(info_log)

    error_log = logging.FileHandler(f"{log_dir}/{dtc_name}_error.log")
    error_log.setFormatter(formatter)
    error_log.setLevel(logging.ERROR)
    logger.addHandler(error_log)

    console_log = logging.StreamHandler()
    console_log.setFormatter(formatter)
    console_log.setLevel(logging.ERROR)
    logger.addHandler(console_log)

    if is_debug:
        console_log.setLevel(logging.DEBUG)
    elif is_interactive:
        console_log.setLevel(logging.INFO)

    return logger

# Usage example
def main():
    # Set up the logger with debug mode enabled
    logger = setup_logger('ExampleLogger', '.', is_debug=False, is_interactive=False)
    
    for handler in logger.handlers:
        print(f"Handler: {handler} | Level: {logging.getLevelName(handler.level)}")
    
    # Log some messages at different levels
    logger.debug('This is a debug message')
    logger.info('This is an info message')
    logger.warning('This is a warning message')
    logger.error('This is an error message')
    logger.critical('This is a critical message')

if __name__ == "__main__":
    main()

运行输出:

$ python3 test_logger.py
Handler: <FileHandler /mnt/c/3e/datacollector/lib/pylib/ExampleLogger.log (INFO)> | Level: INFO
Handler: <FileHandler /mnt/c/3e/datacollector/lib/pylib/ExampleLogger_error.log (ERROR)> | Level: ERROR
Handler: <StreamHandler <stderr> (INFO)> | Level: INFO
2023-11-27 16:42:16,304 244 WARNING - This is a warning message
2023-11-27 16:42:16,305 244 ERROR - This is an error message
2023-11-27 16:42:16,305 244 CRITICAL - This is a critical message

问题原因

核心问题在于Logger对象本身的级别未配置。Python logging模块采用两级过滤机制:

  1. Logger自身级别:只有级别≥该值的日志才会被传递给handler;
  2. Handler级别:只有级别≥该值的日志才会被输出。

默认情况下,Logger的级别是logging.WARNING,所以INFO及以下级别的日志会被Logger直接过滤,根本不会传到handler——哪怕handler已经设置为INFO级别也没用。上述代码只配置了handler的级别,完全忽略了Logger本身的级别设置。

修复方案

在setup_logger函数中,添加Logger级别的配置,确保它的级别低于或等于所有handler的级别,让handler来决定最终输出哪些日志。最稳妥的方式是将Logger级别设为最低的DEBUG,这样所有日志都会传递给handler,由各个handler自己的级别控制输出:

import logging

def setup_logger(dtc_name, log_dir, is_debug=False, is_interactive=False):
    formatter = logging.Formatter("%(asctime)s %(process)s %(levelname)s - %(message)s")

    logger = logging.getLogger(dtc_name)
    if logger.handlers:
        for handler in logger.handlers[:]:
            logger.removeHandler(handler)
    
    # 关键修复:设置Logger本身的级别为DEBUG,确保所有日志都能传递到handler
    logger.setLevel(logging.DEBUG)

    info_log = logging.FileHandler(f"{log_dir}/{dtc_name}.log")
    info_log.setFormatter(formatter)
    info_log.setLevel(logging.INFO)
    logger.addHandler(info_log)

    error_log = logging.FileHandler(f"{log_dir}/{dtc_name}_error.log")
    error_log.setFormatter(formatter)
    error_log.setLevel(logging.ERROR)
    logger.addHandler(error_log)

    console_log = logging.StreamHandler()
    console_log.setFormatter(formatter)
    console_log.setLevel(logging.ERROR)
    logger.addHandler(console_log)

    if is_debug:
        console_log.setLevel(logging.DEBUG)
    elif is_interactive:
        console_log.setLevel(logging.INFO)

    return logger

# 用法示例
def main():
    # 设置is_interactive=True测试INFO输出
    logger = setup_logger('ExampleLogger', '.', is_debug=False, is_interactive=True)
    
    for handler in logger.handlers:
        print(f"Handler: {handler} | Level: {logging.getLevelName(handler.level)}")
    
    # 测试不同级别日志
    logger.debug('This is a debug message')
    logger.info('This is an info message')
    logger.warning('This is a warning message')
    logger.error('This is an error message')
    logger.critical('This is a critical message')

if __name__ == "__main__":
    main()

修复后效果

修改后运行脚本,INFO级别日志会正常输出到文件和控制台(当is_interactive=True时),输出类似:

Handler: <FileHandler ./ExampleLogger.log (INFO)> | Level: INFO
Handler: <FileHandler ./ExampleLogger_error.log (ERROR)> | Level: ERROR
Handler: <StreamHandler <stderr> (INFO)> | Level: INFO
2023-11-27 16:42:16,304 244 INFO - This is an info message
2023-11-27 16:42:16,304 244 WARNING - This is a warning message
2023-11-27 16:42:16,305 244 ERROR - This is an error message
2023-11-27 16:42:16,305 244 CRITICAL - This is a critical message

内容的提问来源于stack exchange,提问作者Vexx1988

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.05 00:36:14