python does not release filehandles to logfile

2020-01-25 07:20发布

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.

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

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?

3条回答
来,给爷笑一个
2楼-- · 2020-01-25 07:58

You can also shutdown the logging completely. 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.

查看更多
劳资没心,怎么记你
3楼-- · 2020-01-25 08:00

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.

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

查看更多
小情绪 Triste *
4楼-- · 2020-01-25 08:02

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

When your Run class completes, call:

handlers = self.log.handlers[:]
for handler in handlers:
    handler.close()
    self.log.removeHandler(handler)
查看更多
登录 后发表回答