解决Python logging与第三方日志重复打印问题
解决Python logging第三方库日志重复打印问题
方案1:让自定义日志器完全独立(优先推荐)
核心思路是给你的MyPrintLog日志器添加专属Handler,并禁止它将日志传播到父级(比如root),彻底隔离自定义日志与第三方日志的输出逻辑。
import logging # 初始化自定义日志器 my_logger = logging.getLogger("MyPrintLog") my_logger.setLevel(logging.DEBUG) # 关键配置:关闭日志传播,避免日志被父级日志器的Handler重复输出 my_logger.propagate = False # 添加自定义控制台Handler console_handler = logging.StreamHandler() # 设置自定义日志格式 formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s') console_handler.setFormatter(formatter) my_logger.addHandler(console_handler) # 测试输出:只会通过MyPrintLog的Handler打印一次 my_logger.info("这是自定义日志")
配置后,MyPrintLog的日志只会走自己的Handler输出,第三方库的日志会按其自身配置输出,不会出现重复。
方案2:给Handler添加过滤器
如果项目必须依赖root日志器,可以给root的Handler添加过滤器,精准控制哪些日志能输出。
示例1:只允许MyPrintLog的日志输出
import logging class MyLogFilter(logging.Filter): def filter(self, record): # 仅保留MyPrintLog及其子日志器的日志记录 return record.name.startswith("MyPrintLog") # 找到root日志器中的控制台Handler,添加过滤器 for handler in logging.root.handlers: if isinstance(handler, logging.StreamHandler): handler.addFilter(MyLogFilter())
示例2:排除第三方库的日志
假设第三方库的日志器名称是ThirdParty,直接过滤掉它的日志:
import logging class ExcludeThirdPartyFilter(logging.Filter): def filter(self, record): # 排除ThirdParty及其子日志器的日志记录 return not record.name.startswith("ThirdParty") # 给root的控制台Handler添加过滤器 for handler in logging.root.handlers: if isinstance(handler, logging.StreamHandler): handler.addFilter(ExcludeThirdPartyFilter())
方案3:重置root日志器的Handler
如果第三方库已经给root日志器添加了Handler导致重复,可以先清空root的现有Handler,再重新配置:
import logging # 清空root日志器的所有现有Handler for handler in logging.root.handlers[:]: logging.root.removeHandler(handler) # 重新配置root日志器(可选,也可以直接使用自定义日志器) root_handler = logging.StreamHandler() root_formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s') root_handler.setFormatter(root_formatter) logging.root.addHandler(root_handler) logging.root.setLevel(logging.INFO)
总结
优先选择方案1,它从根源上隔离了自定义日志与第三方日志的输出逻辑,最稳定且不易出错。方案2和3适合必须依赖root日志器的场景。
内容的提问来源于stack exchange,提问作者planetes42
相关产品推荐
相关产品推荐

