python不会释放日志文件的文件句柄

时间:2013-03-15 15:02:58

标签: python logging

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

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

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

主要例程

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) 

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

有没有办法可以强迫这个?

3 个答案:

答案 0 :(得分:48)

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

当您的Run班级完成后,请致电:

handlers = self.log.handlers[:]
for handler in handlers:
    handler.close()
    self.log.removeHandler(handler)

答案 1 :(得分:4)

您也可以完全shutdown the logging。在这种情况下,文件句柄将被释放:

logging.shutdown()

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

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

答案 2 :(得分:0)

我正在使用交互式Python环境(Spyder)。显然,Spyder在内部使用日志记录。因此,logging.shutdown()无法产生预期的效果。相同程序的下一次执行使日志记录增加了一倍,第三次执行使日志记录增加了三倍,依此类推。显然,在这种环境中,处理程序不会被shutdown()删除。另外,我也没有通过发出显式的shutdown()调用来破坏Spyder。令人困惑。

Martijn的一次显式关闭和删除处理程序的代码确实在Spyder环境中起作用。