将Logger日志消息重定向至sys.stdout和sys.stderr的问题求助
解决Python日志分级别重定向到stdout和stderr的问题
我明白你想要实现的需求:把CRITICAL及以上级别的日志输出到sys.stderr,而WARNING到ERROR级别(高于WARNING但低于CRITICAL)的日志输出到sys.stdout。logging.basicConfig()确实没法直接搞定这个需求,因为它只能配置一个默认的日志处理器,没法同时处理两个不同的输出流和级别过滤。咱们得用自定义的StreamHandler来实现这个功能。
下面是完整的可运行代码,我会一步步解释:
import logging import sys # 获取根日志器(或者你可以创建自己的日志器,比如logging.getLogger("my_logger")) logger = logging.getLogger() logger.setLevel(logging.WARNING) # 设置日志器的最低级别,确保所有需要的日志都能被处理 # 先移除默认的handler,避免重复输出 for handler in logger.handlers[:]: logger.removeHandler(handler) # 定义日志格式(可选,你可以根据自己的需求调整) log_format = logging.Formatter("%(asctime)s - %(name)s - %(levelname)s - %(message)s") # 1. 处理CRITICAL及以上级别,输出到stderr stderr_handler = logging.StreamHandler(sys.stderr) stderr_handler.setLevel(logging.CRITICAL) stderr_handler.setFormatter(log_format) logger.addHandler(stderr_handler) # 2. 处理WARNING到ERROR级别,输出到stdout # 先定义一个过滤器,过滤掉CRITICAL级别的日志 class NonCriticalFilter(logging.Filter): def filter(self, record): return record.levelno < logging.CRITICAL stdout_handler = logging.StreamHandler(sys.stdout) stdout_handler.setLevel(logging.WARNING) stdout_handler.addFilter(NonCriticalFilter()) stdout_handler.setFormatter(log_format) logger.addHandler(stdout_handler) # 测试不同级别的日志 logger.debug("这是DEBUG级别的日志,不会被输出") logger.info("这是INFO级别的日志,不会被输出") logger.warning("这是WARNING级别的日志,会输出到stdout") logger.error("这是ERROR级别的日志,会输出到stdout") logger.critical("这是CRITICAL级别的日志,会输出到stderr")
关键步骤解释:
- 日志器级别设置:把根日志器的级别设为
logging.WARNING,这样所有WARNING及以上的日志都会被后续的处理器处理(如果设得更高,比如ERROR,那WARNING日志就会被过滤掉)。 - 移除默认Handler:Python的logging模块默认会添加一个StreamHandler到根日志器,直接输出到stderr,所以我们要先移除它,避免重复输出。
- 两个Handler分工:
stderr_handler只处理CRITICAL及以上的日志,直接指向sys.stderr。stdout_handler处理WARNING及以上的日志,但通过自定义过滤器NonCriticalFilter排除了CRITICAL级别,这样就只会输出WARNING和ERROR到sys.stdout。
- 日志格式:统一设置格式,让日志输出更清晰,你可以根据需要修改格式字符串。
如果你运行这段代码,就能看到WARNING和ERROR输出到标准输出,CRITICAL输出到标准错误,完美符合你的需求。
内容的提问来源于stack exchange,提问作者tweak-wtf
相关产品推荐
相关产品推荐

