如何捕获Python第三方包的控制台输出并转发至自定义日志器?
统一捕获第三方包输出到自定义日志器
一、重定向标准输出/错误到日志器
第三方包的print语句会输出到sys.stdout或sys.stderr,我们可以自定义类替换这两个对象,把所有输出转发到你的日志器。
import sys import logging # 假设你已配置好自定义日志器 logger = logging.getLogger("my_app_logger") class StreamToLogger: """将流输出转发到日志器的工具类""" def __init__(self, logger, log_level=logging.INFO): self.logger = logger self.log_level = log_level def write(self, buf): # 按行处理输出,避免逐字符生成日志 for line in buf.rstrip().splitlines(): self.logger.log(self.log_level, line.rstrip()) def flush(self): # 兼容流的flush方法,无需实际操作 pass # 替换系统标准输出和错误输出 sys.stdout = StreamToLogger(logger, logging.INFO) sys.stderr = StreamToLogger(logger, logging.WARNING)
二、捕获警告信息到日志器
Python的warnings模块负责输出各类警告,替换默认处理器即可将警告转发到日志器:
import warnings def warning_handler(message, category, filename, lineno, file=None, line=None): # 格式化警告信息后,用日志器输出 warning_msg = warnings.formatwarning(message, category, filename, lineno, line) logger.warning(warning_msg.strip()) # 替换默认警告处理器 warnings.showwarning = warning_handler
三、完整整合示例
务必在导入任何第三方包之前执行以下配置,确保所有输出都能被捕获:
import logging import sys import warnings # 1. 配置自定义日志器(示例格式,可根据需求调整) logging.basicConfig( level=logging.INFO, format="[%(asctime)s] %(levelname)-8s %(message)s (%(filename)s:%(lineno)d)", datefmt="%m/%d/%Y %I:%M:%S %p" ) logger = logging.getLogger("my_app_logger") # 2. 重定向标准输出/错误 class StreamToLogger: def __init__(self, logger, log_level=logging.INFO): self.logger = logger self.log_level = log_level def write(self, buf): for line in buf.rstrip().splitlines(): self.logger.log(self.log_level, line.rstrip()) def flush(self): pass sys.stdout = StreamToLogger(logger, logging.INFO) sys.stderr = StreamToLogger(logger, logging.WARNING) # 3. 捕获警告到日志器 def warning_handler(message, category, filename, lineno, file=None, line=None): warning_msg = warnings.formatwarning(message, category, filename, lineno, line) logger.warning(warning_msg.strip()) warnings.showwarning = warning_handler # 4. 导入第三方包并运行应用代码 import matplotlib # ... 你的业务代码 ...
注意事项
- 配置代码必须早于第三方包的导入语句,否则无法捕获包初始化阶段的输出。
- 针对少数直接调用底层输出的C扩展包,这种方法可能无效,但绝大多数纯Python包的输出都能被处理。
- 可根据日志策略调整级别:比如将stderr转发级别设为
logging.ERROR,或把警告输出设为logging.INFO。
内容的提问来源于stack exchange,提问作者Micky-D
相关产品推荐
相关产品推荐

