Proper way to delete/kill a logger?

Jean-Michel Pichavant jeanmichel at sequans.com
Mon Nov 28 08:47:51 EST 2011


cassiope wrote:
> I've been trying to migrate some code to using the standard python
> logging classes/objects.  And they seem quite capable of doing what I
> need them to do.  Unfortunately there's a problem in my unit tests.
> It's fairly common to have to create quite a few entities in the
> course of a series of tests.  What appears to be happening is that the
> loggers don't get entirely eliminated, so that new invocations end up
> spewing output messages from each of the loggers that were started
> with this invocation of the python interpreter.
>
> I haven't found a function within the logging module that completely
> kills a given instance.  The removeHandler() function seems to leave a
> stdout/stderr output even if all the assigned handlers have been
> removed.  I've tried a few workarounds, such as increasing the level
> to an absurdly large level, which mostly kinda works, and killing the
> old entity before creating the new test version.
>
> There is probably something simple that I'm missing.  If you know what
> that is, please point me to that fine manual - I'd appreciate it.
> Thanks!
>
>     -f
>   
Loggers are static objects managed by the module itself. When you create 
one, it won't be removed until you leave the shell. Thas is way it is 
advise not to create thousands of loggers with different names.
That's the module design, nothing you can do about it.

It takes a little time to get used to it but the logging documentation 
has a lot of examples showing how to use to module.
Your main problem is that some of your test instances are configuring 
the loggers, they should not. Configuration should be done in the 'main' 
function *only*.

import logging, sys

class Test1:
    def __init__(self):
        self.logger = logging.getLogger(self.__class__.__name__) # 
create a new logger or reuse one if a logger with that name already exists
        self.logger.info('I am created')
        # adding a handler to the logger here would be a mistake, 
configuration is let to the user, in this case the program main entry point
        # objects raising log events should not care about how they are 
formated/displayed
class Test2:
    def __init__(self):
        self.logger = logging.getLogger(self.__class__.__name__)
        self.logger.info('I am created')

def main():
    # configure here the logger, usually the root logger
    root = logging.getLogger()
    root.handlers = [] # required if you don't want to exit the shell 
between 2 executions (not very wise)
    root.setLevel(logging.DEBUG)
    root.addHandler(logging.StreamHandler(sys.stdout))
    root.handlers[-1].setFormatter(logging.Formatter('%(name)s - 
%(levelname)s - %(message)s'))

    t1 = Test1()
    t2 = Test2()
    t3 = Test2()

if __name__ == '__main__':
    main()

 > run test.py
Test1 - INFO - I am created
Test2 - INFO - I am created
Test2 - INFO - I am created


JM

PS : one way to cleanup a logger is to remove all its handlers, i.e. 
logger.handlers = [], but if you need to do this you may have done 
something wrong.



More information about the Python-list mailing list