Writing in Python from a library module

I am trying to set up a general log in my Python library modules so that they use the logger configured in the calling module without having to hard-code the logger name. I have seen many examples using logging.basicConfig()

in the calling module and the caller logging.debug()

in the library module, but it doesn't work when I set up my own StreamHandler. What am I doing wrong?

This is my calling module:

import logging, logging.handlers
logger = logging.getLogger(__name__)
logger.setLevel(logging.INFO)
consolehandler = logging.StreamHandler()
consoleformatter = logging.Formatter('[%(name)s] %(levelname)s %(message)s')
consolehandler.setFormatter(consoleformatter)
logger.addHandler(consolehandler)
import libmodule

def run():
    logger.info("message from calling module")
    libmodule.say("message from library module")

      

I tried this in libmodule.py:

import logging

def say(msg):
    logging.info(msg)

      

and this:

import logging
logger = logging.getLogger()

def say(msg):
    logger.info(msg)

      

But in both cases, when I call run (), I get this output:

[callingmodule] INFO message from calling module

      

but expected this:

[callingmodule] INFO message from calling module
[callingmodule] INFO message from library module

      

+3


source to share


1 answer


This is because in the first case, you get the logger by name, and in the second, only the getLogger()

one that returns the root log. It's not the same and you don't have a custom stream handler.

An easier way to do this is to follow the directions in the docs here :

'Multiple calls to getLogger () with the same name will always return a reference to the same Logger object. '

In other words, if you just use getLogger('my_common_name')

in both places, then both of them will automatically point to the same log, even if you configured it in the same place.

Added: If you want to write the logger from the parent then you will do something like this in your library:



# In libmodule

_log = None

def initLogger(logger=None):
    global _log
    if logger != None:
        _log = logger
    else:
        import logging
        _log = logging.getLogger()

# Later in the module
def say(message):
    _log.info(message)

      

then in your parent module:

# In the parent module
mylog = a logger i set up

import libmodule
libmodule.initLogger(mylog)

      

This should make them point to the same log.

+2


source







All Articles