Python logging in interactive sessions
Question: I am trying to implement logging in my Python 2.7 applications and have found
it very useful. However, I have noticed that when running Python interactively
each logging message prints multiple times. The number of times the message is
printed is the same as the number of times I have previously run the script,
so it seems that the logger is not being cleaned up properly at the end of the
script (I would guess). Consider the following example:

    
    
    import sys
    import logging
    
    def main(argv=None):
    
        log = logging.getLogger('test')
        log.setLevel(logging.DEBUG)
    
        console_handler = logging.StreamHandler()
        console_handler.setFormatter(logging.Formatter("%(message)s"))
        log.addHandler(console_handler)
    
        log.info('Starting something...')
        log.info('Doing something...')
        log.info('Finished something.')
    
        logging.shutdown()
    
    if __name__=='__main__':
        sys.exit(main(sys.argv[1:]))
    

Typing

    
    
    >>> import file.py
    >>> file.main()
    

yields the following:

    
    
    Starting something...
    Doing something...
    Finished something.
    

Then typing `file.main()` a second time yields:

    
    
    Starting something...
    Starting something...
    Doing something...
    Doing something...
    Finished something.
    Finished something.
    

Repeating a third time would give three or each message and so on. Does anyone
know why this is happening - is this the expected behaviour of the logging
module and, if so, how can I change this? The above script only prints one of
each message if run as a script (`python file.py`), as expected.


Answer: Yes, you are creating and reusing a single instance of your logger. Each
handler added to that logger is also logging a message.

You probably want logging setup to be at the module level or in a separate
function so you only run it once.

Maybe something like this:

    
    
    import atexit
    import sys
    import logging
    
    log = logging.getLogger('test')
    log.setLevel(logging.DEBUG)
    
    console_handler = logging.StreamHandler()
    console_handler.setFormatter(logging.Formatter("%(message)s"))
    log.addHandler(console_handler)
    
    def shutdown_logging():
        logging.shutdown()    
    
    atexit.register(shutdown_logging)
    
    def main(argv=None):
        log.info('Starting something...')
        log.info('Doing something...')
        log.info('Finished something.')
    
    
    if __name__=='__main__':
        sys.exit(main(sys.argv[1:]))
    

