gpt4 book ai didi

python - 如何在多个模块中使用 logging.getLogger(__name__)

转载 作者:太空狗 更新时间:2023-10-29 17:16:26 27 4
gpt4 key购买 nike

来自logging howto对于 Python 2.7(我的重点):

A good convention to use when naming loggers is to use a module-level logger, in each module which uses logging, named as follows:

logger = logging.getLogger(__name__)

This means that logger names track the package/module hierarchy, and it’s intuitively obvious where events are logged just from the logger name.

听起来不错。

现在,logging cookbook为多个模块提供了一个示例,它使用硬编码的记录器名称而不是 __name__ 常量。在示例的“主模块”中,我们发现

logger = logging.getLogger('spam_application')

在我们发现的“辅助模块”中

module_logger = logging.getLogger('spam_application.auxiliary')

我将这个示例逐字复制到具有以下结构的包文件夹中:

cookbook-example
|- __init__.py
|- main_module.py
|- auxiliary_module.py

这运行没有问题,从主模块和辅助模块产生预期的日志输出,但事情是这样的:

如果我现在按照 logging howto 的建议用 __name__ 常量替换硬编码的记录器名称,食谱示例出现故障:我只从主模块获取日志消息,但没有从辅助模块获取日志消息。

我一定遗漏了一些明显的东西。知道我做错了什么吗?

注意:

有很多非常相似的问题和相关答案,例如:1 , 2 , 3 , 4 , 5 , 6 , 还有很多。但是,这些似乎都没有解决这个具体问题。

--编辑--

这是一个基于食谱示例的最小示例,其中显式名称字符串替换为 __name__

主模块.py

import logging
import auxiliary_module

# create and configure main logger
logger = logging.getLogger(__name__)
logger.setLevel(logging.DEBUG)
# create console handler with a higher log level
handler = logging.StreamHandler()
handler.setLevel(logging.DEBUG)
# create formatter and add it to the handler
formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
handler.setFormatter(formatter)
# add the handler to the logger
logger.addHandler(handler)

logger.info('message from main module')
auxiliary_module.some_function()

auxiliary_module.py

import logging

# create logger
module_logger = logging.getLogger(__name__)

def some_function():
module_logger.info('message from auxiliary module')

最佳答案

正如@shmee 在 this answer 中指出的那样,必须使用点符号在记录器名称中明确定义记录器层次结构。也就是说,如果 main_module.py 中的记录器名称是例如'a',那么 auxiliary_module.py 中的记录器名称必须是 'a.b'(不仅仅是 'b'),以使其继承logger'a'的配置。 getLogger() documentation中也提到了这一点.

然而,这应该在使用 __name__ 时自动处理,如 logging how-to 中所述:

This means that logger names track the package/module hierarchy, and it’s intuitively obvious where events are logged just from the logger name.

问题是,要使其正常工作,您需要以正确的方式使用 __name__,而我没有这样做。

我的示例中的问题在于 cookbook-example 包文件夹中文件的组织:

主模块和辅助模块都处于同一级别(即在同一文件夹中)。所以,正如解释的here ,主模块的 __name__ 将是 '__main__'(因为它是顶级脚本),而 __name__辅助模块将是 'auxiliary_module'(即文件名),而不是 '__main__.auxiliary_module'

因此,辅助模块中的记录器将是根记录器的子项,而不是 '__main__' 记录器的子项,因此它将继承根记录器配置(仍然具有默认日志记录级别 WARNING) 而不是主模块中指定的配置。

因此,为了使示例正常运行,我们有多种选择:

  1. main 模块中的 getLogger(__name__) 替换为 getLogger()。这会将配置应用于根记录器,因此也应用于辅助模块记录器,正如@shmee 所建议的那样。

  2. auxiliary 模块中的 getLogger(__name__) 替换为getLogger('__main__.' + __name__)。结果将是等价的到原始的食谱示例(除了主记录器现在被称为'__main__' 而不是 'spam_application')。

关于python - 如何在多个模块中使用 logging.getLogger(__name__),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50714316/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com