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

如何用Python 3 logging按级别输出到stdout和stderr?

Python 3 logging 模块分级别输出到 stdout/stderr

要实现logging.debug()、logging.info()输出到stdout,logging.warning()、logging.error()输出到stderr,核心思路是给日志系统添加两个不同的StreamHandler,分别绑定到不同输出流,并通过过滤器或级别控制各自处理的日志等级。

方法一:基础实现(精准级别过滤)

直接为两个Handler配置对应输出流,并用过滤器限定处理的日志级别,同时确保根Logger能传递所有需要的日志:

import logging
import sys

# 设置根Logger级别为DEBUG,确保所有级别日志都能进入处理流程
logging.basicConfig(level=logging.DEBUG)

# 创建绑定stdout的Handler,仅处理DEBUG和INFO级日志
stdout_handler = logging.StreamHandler(sys.stdout)
stdout_handler.setLevel(logging.DEBUG)
class StdoutFilter(logging.Filter):
    def filter(self, record):
        return record.levelno in (logging.DEBUG, logging.INFO)
stdout_handler.addFilter(StdoutFilter())

# 创建绑定stderr的Handler,处理WARNING及以上级日志
stderr_handler = logging.StreamHandler(sys.stderr)
stderr_handler.setLevel(logging.WARNING)

# 移除basicConfig自动添加的默认Handler,避免重复输出
root_logger = logging.getLogger()
for handler in root_logger.handlers[:]:
    root_logger.removeHandler(handler)

# 为根Logger添加两个自定义Handler
root_logger.addHandler(stdout_handler)
root_logger.addHandler(stderr_handler)

# 测试输出
logging.debug("这是debug日志,将输出到stdout")
logging.info("这是info日志,将输出到stdout")
logging.warning("这是warning日志,将输出到stderr")
logging.error("这是error日志,将输出到stderr")

方法二:带自定义格式的进阶实现

如果需要为不同输出流设置差异化的日志格式,可以给每个Handler单独配置Formatter:

import logging
import sys

# 定义不同输出流的日志格式
stdout_formatter = logging.Formatter('%(asctime)s | %(levelname)s | %(message)s')
stderr_formatter = logging.Formatter('%(asctime)s | %(levelname)s | %(filename)s:%(lineno)d | %(message)s')

# 配置stdout Handler
stdout_handler = logging.StreamHandler(sys.stdout)
stdout_handler.setLevel(logging.DEBUG)
stdout_handler.setFormatter(stdout_formatter)
class StdoutFilter(logging.Filter):
    def filter(self, record):
        return record.levelno <= logging.INFO  # 覆盖DEBUG和INFO级别
stdout_handler.addFilter(StdoutFilter())

# 配置stderr Handler
stderr_handler = logging.StreamHandler(sys.stderr)
stderr_handler.setLevel(logging.WARNING)
stderr_handler.setFormatter(stderr_formatter)

# 初始化根Logger
root_logger = logging.getLogger()
root_logger.setLevel(logging.DEBUG)
# 清理默认Handler
for handler in root_logger.handlers[:]:
    root_logger.removeHandler(handler)
root_logger.addHandler(stdout_handler)
root_logger.addHandler(stderr_handler)

# 测试
logging.debug("debug级信息,输出到stdout")
logging.info("info级信息,输出到stdout")
logging.warning("warning级信息,输出到stderr")
logging.error("error级信息,输出到stderr")

关键注意点

  • 必须移除basicConfig自动生成的默认StreamHandler,否则会导致日志重复输出(默认Handler默认绑定stderr)。
  • 根Logger的级别需设置为所需的最低级别(示例中为DEBUG),否则低于该级别的日志会被直接拦截,无法传递到Handler。
  • 使用Filter可以更灵活地控制日志流向,相比单纯设置Handler级别,能精确指定特定级别或级别范围。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.05 14:05:16