首页 文章

从库模块中记录Python

提问于
浏览
4

我正在尝试在我的Python库模块中设置通用日志记录,以便它们使用在调用模块中配置的 Logger ,而无需硬编码 Logger 名称 . 我在调用模块中看到了大量使用 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 回答

  • 2

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

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

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

    换句话说,如果你只是在两个地方使用 getLogger('my_common_name') ,那么即使你在一个地方定制了它们,它们也会自动指向同一个 Logger .

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

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

    这应该使它们都指向同一个 Logger .

相关问题