Python库模块中的日志记录

12
我正在尝试在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个回答

8
那是因为在第一个实例中,您通过名称获取记录器,在第二个实例中,您只是使用getLogger(),它返回根记录器。这不是相同的记录器,并且没有安装自定义流处理程序。
更简单的方法是遵循文档here中的指导:

'多次使用相同名称调用getLogger()将始终返回对同一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)

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


谢谢您的回复,Corley。这意味着在我的库代码中硬编码常用名称,并且只有当库的用户选择相同的常用名称时才能起作用。 - Bruce Alport
1
好的,你现在正在做这件事,有点像(两个人都在查看中央日志模块并寻找硬编码记录器,一个是__file__,另一个是根;两者都没有直接相互查看)。你是想允许用户将库记录器重定向到他们自己的记录器吗?标准的方法是有一个initLogger()函数来初始化库记录器,你可以传递一个记录器进去。如果没有传入记录器,它会创建自己的记录器。就像这样。 - Corley Brigman
你说得对,我想将库记录器重定向到用户配置的记录器中,但我希望能够自动完成。initLogger() 方法听起来很有趣。你能给我指出一个例子吗? - Bruce Alport
添加了一个简单的示例。 - Corley Brigman
太好了!谢谢 Corley。 - Bruce Alport

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接