Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/logging/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
python不会将文件句柄释放到日志文件_Python_Logging - Fatal编程技术网

python不会将文件句柄释放到日志文件

python不会将文件句柄释放到日志文件,python,logging,Python,Logging,我有一个应用程序,它必须运行许多模拟运行。我想设置一个日志机制,其中所有日志记录都记录在general.log中,模拟运行的所有日志都转到run00001.log。。。。为此,我定义了一个类运行。在\uuuu init\uuuu()中,为运行日志添加了一个新的文件句柄 问题是运行的日志文件永远不会被释放,因此在多次运行之后,可用的句柄将耗尽,运行将崩溃 我已经设置了一些例程来测试它,如下所示 import logging class Run(object): """ Implement

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

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

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

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) 
主要程序

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')
类运行在模块模型中定义如下

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) 
然后,我使用程序进程资源管理器来跟踪文件处理程序。我看到运行日志出现,但从未消失


有什么方法可以强制执行此操作吗?

您需要在filehandler上调用
.close()

当您的
运行
课程完成时,调用:

handlers = self.log.handlers[:]
for handler in handlers:
    handler.close()
    self.log.removeHandler(handler)
你也完全可以。在这种情况下,将释放文件句柄:

logging.shutdown()
它关闭所有已配置日志处理程序的打开句柄


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

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


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

为什么不在运行完成后再次删除处理程序?想必你能参加那个活动?有什么建议吗?我已经尝试过在_del__()中指定self.log.removeHandler(myhandler),甚至是显式调用析构函数(myrun._del__())。我还尝试指定in _uexit__;()并使用with语句,正如使用open打开文件句柄时建议的那样。但是到目前为止还没有成功。您还需要在filehandler上调用
.close()
self.log.handlers[0].close()
应该足够了,真的。但是,在这个调用之后,您不能使用日志系统-只是一个提醒。这并不能完全关闭日志记录。它在每个处理程序上调用
flush()
close()
。虽然
.close()
将处理程序从全局模块状态中删除,并且在shutdown()调用后不会再次关闭,但文件处理程序通常会在下一条日志消息中重新打开其文件句柄。由于它们尚未从其父记录器中删除,这只意味着它们再次打开该文件以写入下一个传入日志记录,然后无法在下一次关闭调用时关闭。将使用
logging.shutdown()
的命令留给解释器。@ShitalShah:至少在涉及文件处理程序及其子类时,您可以这样做(流处理程序,例如控制台,是
FileHandler
的父类,并且不这样做)
logging.shutdown()
只会刷新和关闭已注册的处理程序,并且
Handler.close()
在关闭时从全局注册表中取消注册处理程序。就这样。处理程序仍然连接到记录器,日志记录仍然会将记录传递给处理程序,因此如果它们有地方可以发送到,它们仍然可以发送这些记录。@MartijnPieters-如果我想删除文件处理程序打开时使用的临时文件,唯一的方法就是使用logging.shutdown()。我宁愿关闭那个处理器。我是否还需要完全删除处理程序?@CyberSamurai:每次新日志消息到达时,文件处理程序都会自动重新打开配置的文件名,因此调用
handler.close()
有时可能会显得徒劳。从记录器中删除处理程序将停止向其发送未来的日志记录。
logging.shutdown()
只需调用
handler.flush()
handler.close()
,我不建议使用它。它使日志模块处于无法再次使用
logging.shutdown()
的状态,这是不可靠的。