55

我有一个必须运行许多模拟运行的应用程序。我想设置一个日志记录机制,其中所有日志记录都记录在 general.log 中,模拟运行的所有日志都转到 run00001.log,...。为此,我定义了一个类 Run。为运行日志添加了__init__()一个新的文件句柄。

问题是运行的日志文件永远不会被释放,因此在多次运行后可用的句柄被耗尽并且运行崩溃。

我已经设置了一些例程来测试它,如下所示

主程序

import Model
try:
    myrun = Model.Run('20130315150340_run_49295')
    ha = raw_input('enter')
    myrun.log.info("some info")
except:
    traceback.print_exc(file=sys.stdout)

ha = raw_input('enter3')

类 Run 在模块 Model 中定义如下

import logging
class Run(object):

    """ Implements the functionality of a single run. """
    def __init__(self, runid):
        self.logdir="."
        self.runid          = runid
        self.logFile        = os.path.join(self.logdir , self.runid + '.log')
        self.log            = logging.getLogger('Run'+self.runid)
        myformatter         = logging.Formatter('%(asctime)s %(name)-12s %(levelname)-8s %(message)s')
        myhandler      = logging.FileHandler(self.logFile)
        myhandler.setLevel(logging.INFO)
        myhandler.setFormatter(myformatter)
        self.log.addHandler(myhandler) 

然后我使用程序进程资源管理器来跟踪文件处理程序。我看到运行日志出现了,但从未消失。

有没有办法我可以强制这样做?

4

4 回答 4

98

您需要调用.close()文件处理程序。

当您的Run课程完成时,请致电:

handlers = self.log.handlers[:]
for handler in handlers:
    handler.close()
    self.log.removeHandler(handler)
于 2013-03-18T10:29:14.077 回答
34

您也可以完全关闭日志记录。在这种情况下,正在释放文件句柄:

logging.shutdown()

它关闭所有已配置的日志记录处理程序的打开句柄。

我需要它能够在单元测试完成后删除日志文件,并且我能够在调用该logging.shutdown()方法后立即删除它。

于 2018-11-14T14:58:36.077 回答
7

我使用的是交互式 Python 环境(Spyder)。显然,Spyder 在内部使用日志记录。因此, logging.shutdown() 不会产生预期的效果。同一程序的下一次执行使日志记录翻了一番,第三次执行使它们增加了三倍,等等。在此环境中,shutdown() 显然不会删除处理程序。此外,我并没有通过发出明确的 shutdown() 调用以任何方式破坏 Spyder。令人费解。

Martijn 的代码一次一个地显式关闭和删除处理程序,在 Spyder 环境中确实有效。

于 2019-05-26T19:52:30.320 回答
0

可能我们只想要's.close()FileHandler不是其他人,所以接受的答案可以稍微修改如下:

for handler in self.log.handlers:
    if isinstance(handler, logging.FileHandler):
        handler.close()

此外,对于我们只配置了一个记录器的更简单的情况,logging.basicConfig()可以通过调用来检索处理程序logging.getLogger().handlers

于 2021-09-29T11:00:13.430 回答