当前位置: 首页 > 面试题库 >

如何在多个模块中使用logging.getLogger(__ name__)

徐帅
2023-03-14
问题内容

从Python
2.7的logginghowto(我的重点):

命名记录器时,一个好的习惯是在每个使用日志记录的模块中使用模块级记录器,命名如下:

logger = logging.getLogger(__name__)

这意味着记录器名称跟踪包/模块的层次结构 ,并且从记录器名称中记录事件的地方就很明显了。

听起来像个好建议。

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

logger = logging.getLogger('spam_application')

在“辅助模块”中

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

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

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

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

如果现在__name__按照logginghowto的建议,用常数替换硬编码的记录器名称,则本食谱示例将崩溃:我仅从主模块获取记录消息,而从辅助模块中获取不到任何消息。

我肯定想念一些明显的东西。有什么想法我做错了吗?

注意:

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

- 编辑 -

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

main_module.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()

assistant_module.py

import logging

# create logger
module_logger = logging.getLogger(__name__)

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

问题答案:

正如@shmee在此答案中指出的那样,必须在记录器名称中使用点符号显式定义记录器层次结构。也就是说,如果in中的记录器名称main_module.py'a',则in的记录器名称auxiliary_module.py必须为'a.b'(而不仅仅是'b'),以便它继承logger的配置'a'getLogger()文档中也提到了这一点。

然而,这应该会自动使用时的照顾__name__,如在提到logging如何做:

这意味着记录器名称跟踪程序包/模块的层次结构,并且从记录器名称中记录事件的地方就很明显了。

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

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

主模块和辅助模块都处于同一级别(即,在同一文件夹中)。所以,作为解释这里的__name__主模块将是'__main__'(因为它是顶级脚本),以及__name__用于辅助模块会'auxiliary_module'(即文件名),NOT
'__main__.auxiliary_module'

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

因此,为使示例正常工作,我们有几种选择:

  1. 更换getLogger(__name__)主要 的模块getLogger()。如@shmee所建议的那样,这会将配置应用于根记录器,从而也应用于辅助模块记录器。

  2. 替换getLogger(__name__)辅助 由模块 getLogger('__main__.' + __name__)。结果将与原始食谱示例相同(除了现在调用主记录器 '__main__'代替'spam_application')。



 类似资料:
  • 问题内容: 我有几个模块-假设是server.js,module1.js,…,moduleN.js。 我想在server.js中定义日志文件: 然后在我所有的模块中使用它 最好的方法是什么?我可以在每个模块中,然后在server.js中进行设置,但是还有更好的解决方案吗? 先感谢您! 问题答案: 默认的记录器概念很好地解决了这一问题。 Winston定义了一个默认记录器,任何对Winston的直接

  • 问题内容: 我已使用以下命令“ go mod init database”在“数据库”文件夹中的“ GOPATH”之外创建了个人使用的模块库,但我不知道: 如何在其他模块中使用/ 导入 该模块? 操作系统: Windows 7 ,Go: v1.11 问题答案: 最简单,可行的现成解决方案是将您的包/模块放入VCS(例如github.com),因此其他包(在其他模块内部)可以通过导入来简单地引用它:

  • 我的代码结构如下: 事件 消息 其他代码 功能测试 在jacoco的构建脚本中,首先它必须复制所有类并使用该类目录来运行该工具。您能描述一下在这里编写目标目录的步骤吗。我的意思是,我应该如何提及运行代码覆盖的目录。 构建时,每个文件夹都有自己的目标文件夹,其中包含类。 以下是步骤: 在詹金斯将项目作为工作进行构建 将其部署到用户阶段 在詹金斯中运行雅各布报告作业 雅高报告工作说明: > 构建步骤-

  • 在我的Android应用程序项目中,我试图避免在我的项目中引用一个外部Maven库,否则我会从那里加载多个。组成一个SDK的aar工件。 相反,我想将 .aar 文件放入我的项目中,然后从我的一个 Gradle Android 库模块中引用它们。 我已经尝试了不同的方法——但都不管用。 灵感来自 https://stackoverflow.com/a/72672032/35689 在这里,我的工件

  • 我有一个小的python项目,它有如下结构-- 我计划使用默认日志模块将消息打印到stdout和一个日志文件。要使用日志模块,需要进行一些初始化- 目前,我在开始记录消息之前在每个模块中执行此初始化。是否有可能在一个地方只执行一次初始化,以便通过在整个项目中进行日志记录来重用相同的设置?

  • 问题内容: 我有一个具有以下结构的小型python项目- 我计划使用默认的日志记录模块将消息打印到stdout和日志文件。要使用日志记录模块,需要进行一些初始化- 目前,在开始记录消息之前,我会在每个模块中执行此初始化。是否可以只在一个位置执行一次初始化,以便通过在整个项目中记录日志来重复使用相同的设置? 问题答案: 最佳实践是在每个模块中都定义一个记录器,如下所示: 在模块顶部附近,然后在模块中