从库模块中记录Python

时间:2014-10-16 13:34:21

标签: python logging

我正在尝试在我的Python库模块中设置通用日志记录,以便它们使用在调用模块中配置的记录器,而无需硬编码记录器名称。我在调用模块中看到了大量使用logging.basicConfig()并在库模块中调用logging.debug()的示例,但在配置我自己的StreamHandler时它并不起作用。我究竟做错了什么?

这是我的通话模块:

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")

我在libmodule.py中试过这个:

import logging

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

和此:

import logging
logger = logging.getLogger()

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

但是在我调用run()的两种情况下,我得到了这个输出:

[callingmodule] INFO message from calling module

但是期待着这个:

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

1 个答案:

答案 0 :(得分:2)

这是因为在第一个实例中,您按名称获取了一个记录器,而在第二个实例中,您只需使用getLogger(),它将返回根记录器。哪个不是同一个,并且没有安装自定义流处理程序。

更简单的方法是遵循文档here中的指导:

  

'对具有相同名称的getLogger()的多次调用将始终返回a   引用相同的Logger对象。'

换句话说,如果您只在两个地方使用getLogger('my_common_name'),那么即使您已在一个地方对其进行了自定义,它们也会自动指向同一个记录器。

补充:如果您想从父级捕获记录器,那么您可以在库中执行以下操作:

# 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)

然后在你的父模块中:

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

import libmodule
libmodule.initLogger(mylog)

这应该使它们都指向同一个记录器。