This issue tracker has been migrated to GitHub, and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

Author DDGG
Recipients DDGG
Date 2013-11-08.03:40:02
SpamBayes Score -1.0
Marked as misclassified Yes
Message-id <1383882003.26.0.546663037949.issue19523@psf.upfronthosting.co.za>
In-reply-to
Content
Issue File: Python26\Lib\logging\__init__.py

class FileHandler(StreamHandler):
    """
    A handler class which writes formatted logging records to disk files.
    """
    def __init__(self, filename, mode='a', encoding=None, delay=0):
        """
        Open the specified file and use it as the stream for logging.
        """
        #keep the absolute path, otherwise derived classes which use this
        #may come a cropper when the current directory changes
        if codecs is None:
            encoding = None
        self.baseFilename = os.path.abspath(filename)
        self.mode = mode
        self.encoding = encoding
        if delay:
            #We don't open the stream, but we still need to call the
            #Handler constructor to set level, formatter, lock etc.
            Handler.__init__(self)   ## 1. here will insert instance into logging._handlerList
            self.stream = None
        else:
            StreamHandler.__init__(self, self._open())

    def close(self):
        """
        Closes the stream.
        """
        if self.stream:   ## 2. when delay=1, here should call Handler.close(self), or the instance still store in logging._handlerList, lead to leak (instance's owner's __del__ will not be called).
            self.flush()
            if hasattr(self.stream, "close"):
                self.stream.close()
            StreamHandler.close(self)
            self.stream = None

------------------------------------------------
leak demo:

import logging
import time

def using_handler():
    filename = "test.log"
    handler = logging.FileHandler(filename, mode="w", delay=1)
    handler.close()

def test():
    while True:
        using_handler()
        time.sleep(.01)

if __name__ == "__main__":
    test()


If you run this script, and then view the Task Manager for this process's handlers, it is growing forever.

------------------------------------
Solution: very easy

Fix the method FileHandler.close:

    def close(self):
        """
        Closes the stream.
        """
        if self.stream:
            self.flush()
            if hasattr(self.stream, "close"):
                self.stream.close()
            StreamHandler.close(self)
            self.stream = None
        else:                       
            Handler.close(self)     


regards
DDGG
History
Date User Action Args
2013-11-08 03:40:03DDGGsetrecipients: + DDGG
2013-11-08 03:40:03DDGGsetmessageid: <1383882003.26.0.546663037949.issue19523@psf.upfronthosting.co.za>
2013-11-08 03:40:03DDGGlinkissue19523 messages
2013-11-08 03:40:02DDGGcreate