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.
--
http://mail.python.org/mailman/listinfo/python-list

Reply via email to