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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/15435652/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-18 20:06:28  来源:igfitidea点击:

python does not release filehandles to logfile

pythonlogging

提问by Bart P.

I have an application which has to run a number of simulation runs. I want to setup a logging mechanisme where all logrecords are logged in a general.log, and all logs for a simulation run go to run00001.log, .... For this I have defined a class Run. in the __init__()a new filehandle is added for the runlog.

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

The problem is that the logfiles for the runs never get released, so after a number of runs the available handles are exhausted and the run crashes.

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

I've set up some routines to test this as follows

我已经设置了一些例程来测试这个如下

main routine

主程序

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')

The class Run is defined in module Model as follows

类 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) 

Then I use the program process explorer to follow the filehandlers. And I see the runlogs appear, but never disappear.

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

Is there a way I can force this?

有什么办法可以强迫我这样做吗?

采纳答案by Martijn Pieters

You need to call .close()on the filehandler.

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

When your Runclass completes, call:

当你的Run类完成后,调用:

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

回答by David Ferenczy Rogo?an

You can also shutdown the loggingcompletely. In that case, file handles are being released:

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

logging.shutdown()

It will close opened handles of all configured logging handlers.

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

I needed it to be able to delete a log file after a unit test is finished and I was able to delete it right after the call to the logging.shutdown()method.

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

回答by Richard Elkins

I was using an interactive Python environment (Spyder). Apparently, Spyder uses logging internally. So, logging.shutdown() does not produce the desired effect. The next execution of the same program doubled log records, the 3rd execution tripled them, etc. Handlers are apparently not removed by shutdown() in this environment. Also, I did not disrupt Spyder in any way by issuing an explicit shutdown() call. Puzzling.

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

Martijn's code to explicitly close and remove the handlers, one at a time, did work in the Spyder environment.

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