首页 > 解决方案 > 如何通过使用“removeHandler(...)”删除所有处理程序来干净地开始多次记录?

问题描述

在开发过程中,我使用 python 日志记录模块。例如,在出现未处理的异常后,我想重新运行程序并重新初始化日志记录。出于某种原因,我似乎无法从日志实例中删除所有处理程序。即便如此,它也从未被删除。

import logging

log = logging.getLogger(__name__)
print('Existing handlers:')
print(log.handlers)

#Remove all handlers:
for handler in log.handlers: #get rid of existing old handlers
    print('removing handler %s'%handler)
    log.removeHandler(handler)

#excpecting "[]" for log.handlers
print('Existing handlers after removal:')
print(log.handlers)

fh1 = logging.StreamHandler()
formatter1 = logging.Formatter('fh1: %(levelname)s - %(message)s')
fh1.setFormatter(formatter1)

fh2 = logging.StreamHandler()
formatter2 = logging.Formatter('fh2: %(levelname)s - %(message)s')
fh2.setFormatter(formatter2)

log.addHandler(fh1)
log.addHandler(fh2)

log.error('Some logging occurs here')

在新的 IPython 控制台中第一次运行时,我得到:

fh1: ERROR - Some logging occurs here
fh2: ERROR - Some logging occurs here
Existing handlers:
[]
Existing handlers after removal:
[]

这几乎是我的预期。出现的顺序让我有点困惑。为什么日志会出现在打印输出之前?第二次启动程序时真的很奇怪:

fh2: ERROR - Some logging occurs here
fh1: ERROR - Some logging occurs here
fh2: ERROR - Some logging occurs here
Existing handlers:
[<StreamHandler stderr (NOTSET)>, <StreamHandler stderr (NOTSET)>]
removing handler <StreamHandler stderr (NOTSET)>
Existing handlers after removal:
[<StreamHandler stderr (NOTSET)>]

似乎删除句柄的 for 循环只执行了一次。结果我得到了 3 个日志条目,这不是我想要的。我预计第二次运行:

Existing handlers:
[<StreamHandler stderr (NOTSET)>, <StreamHandler stderr (NOTSET)>]
removing handler <StreamHandler stderr (NOTSET)>
removing handler <StreamHandler stderr (NOTSET)>
Existing handlers after removal:
[]
fh1: ERROR - Some logging occurs here
fh2: ERROR - Some logging occurs here

我似乎错过了一些概念。+ 为什么 for 循环只运行一次,虽然len(log.handlers)第一次运行后返回 2,第二次运行后返回 3?

我正在使用 python 3.7.1 并记录 0.5.1.2

标签: pythonpython-3.xlogging

解决方案


我认为这个问题与您的系统操作系统和您的计算机硬件特性更相关。一切正常,并且在我这边连续打印 大约 3 个日志条目 -模块

中的刷新文本可能存在相同的问题 注意:在删除日志处理程序的部分,您应该在迭代之前复制此列表。这就是您没有清除所有日志记录处理程序的原因。像这样:logging

#Remove all handlers:
    for handler in log.handlers[:]: #get rid of existing old handlers
        print('removing handler %s'%handler)
        log.removeHandler(handler)

推荐阅读