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

Python logging模块中自定义BufferingHandler未被正确关闭与移除的问题求助

Python logging模块中自定义BufferingHandler未被正确关闭与移除的问题求助

大家好,我遇到了Python logging模块的一个棘手问题,想请各位帮忙分析下原因:为什么close_handlers函数没有遍历所有MyHandler类型的处理器呢?

当我运行下面的脚本时,thing_1的finally块里第一次调用close_handlers,看起来只关闭了set_up_logging中添加到根日志器的2个处理器里的1个。等执行到thing_2的finally块调用close_handlers时,它居然关闭了3个处理器,而之前那次被“漏掉”的处理器,已经把4条日志语句全加到自己的缓冲区里了。

我原本预期的是:thing_1的所有处理器都会被刷新并移除,thing_2也会重复这个流程,但实际表现完全不符合预期。

我的使用场景是:收集特定函数调用的日志,发送到独立的消息服务,希望每个函数调用的日志都被完整收集后,作为格式化的组发送。现在我发送的格式化消息出现了重复、重叠的问题,根源应该就是处理器没在预期时机被正确关闭。我每次都会关闭并重新添加处理器,因为需要当前函数调用的信息来格式化每条消息的标题。

import logging
from logging.handlers import BufferingHandler

_logger = logging.getLogger(__name__)

class MyHandler(BufferingHandler):
    def __init__(self, capacity: int):
        super().__init__(capacity)

    def flush(self):
        print(self.buffer)
        super().flush()

def set_up_logging():
    logging.basicConfig()
    root_logger = logging.getLogger()
    root_logger.setLevel(logging.INFO)
    root_logger.addHandler(MyHandler(10))
    root_logger.addHandler(MyHandler(5))

def close_handlers():
    for handler in logging.getLogger().handlers:
        if isinstance(handler, MyHandler):
            logging.getLogger().removeHandler(handler)
            handler.close()

def thing_1():
    try:
        set_up_logging()
        _logger.info("hi")
        _logger.error("something went wrong")
    finally:
        print(len(logging.getLogger().handlers))
        close_handlers()

def thing_2():
    try:
        set_up_logging()
        _logger.info("hi again")
        _logger.error("something else went wrong")
    finally:
        print(len(logging.getLogger().handlers))
        close_handlers()

if __name__ == "__main__":
    thing_1()
    thing_2()

备注:内容来源于stack exchange,提问作者henryn

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.20 06:09:30