首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >在使用多个模块进行日志记录时,记录器层次结构和根记录器

在使用多个模块进行日志记录时,记录器层次结构和根记录器
EN

Stack Overflow用户
提问于 2019-10-01 16:12:13
回答 1查看 2.7K关注 0票数 9

我有这样的设置:

代码语言:javascript
运行
复制
main.py
/module
/module/__init__.py (empty)
/module.py

下面是我的两个文件main.pymodule.py的代码:

main.py

代码语言:javascript
运行
复制
import logging
from module import module

logger = logging.getLogger(__name__)

def test():
    logger.warning('in main.py/test')

def main():
    handler = logging.StreamHandler()
    handler.setLevel(logging.INFO)
    formatter = logging.Formatter('%(asctime)s %(name)s/%(module)s [%(levelname)s]: %(message)s', '%Y-%m-%d %H:%M:%S')
    handler.setFormatter(formatter)
    logger.addHandler(handler)

    logger.warning('in main.py/main')
    module.something()

if __name__ == "__main__":
    main()    

module.py

代码语言:javascript
运行
复制
import logging
logger = logging.getLogger(__name__)

def something():
    logger.warning('in module.py/something')

因此,我注意到它输出了以下内容(注意模块记录器没有格式化):

代码语言:javascript
运行
复制
2019-10-01 09:03:40 __main__/main [WARNING]: in main.py/main
in module.py/something

似乎只有在我在main.py中进行编辑以将logger = logging.getLogger( __ name __ )更改为logger = logging.getLogger() def main():之后添加logger = logging.getLogger()之后,它才会像这样记录(这正是我想要的):

代码语言:javascript
运行
复制
2019-10-01 09:04:13 root/main [WARNING]: in main.py/main
2019-10-01 09:04:13 module.module/module [WARNING]: in module.py/something

为什么会这样呢?我认为,因为main.py正在导入module.py,所以在分层规模上它自然会更高,因此module.py将继承main.py中定义的记录器设置。是否需要显式设置主根记录器(使用logger = logging.getLogger())才能使继承工作?我是否没有正确配置我的文件夹结构,使module.py的记录器继承main.py的记录器设置,还是文件夹结构无关?

我之所以问这个问题,是因为我认为应该在整个过程中使用logger = logging.getLogger( __ name __ ) (甚至在main.py中),然后基于导入结构(或文件夹结构?)来确定层次结构和记录器将相应继承。我之所以做出这样的假设,是因为如果我将main.py导入到另一个程序中怎么办?我想我的观点是,我想使日志记录尽可能通用,这样我就可以将一个模块导入另一个模块,并且它总是继承父模块的记录器设置。是否有方法显示所有模块的底层层次结构,以便进行调试/学习?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2019-10-04 06:20:06

日志层次结构与程序中的文件结构无关。层次结构仅由记录器的名称确定。配置记录器时,所有其名称前缀为其名称的记录器都是其子程序,除非另有明确说明,否则将继承其配置。

在您的示例中,日志设置更多地与执行顺序和您所选择的名称有关。当程序运行时,它会执行以下操作:

由于import logging

  • Runs module.py
  1. 从标准库运行logging.py,以实现main中的logger属性,并命名为__main__.
  2. Create a test function
  3. Create a main函数H 220H 121运行主函数H 222G 223

这一系列事件的一些后果:

  • module.logger是在main.logger之前创建的。这并不影响您所看到的行为,但是如果您将circumstances.
  • main.logger作为脚本调用main,则在main是命名为main的情况下值得注意。如果您看到的行为称为main,则行为不会改变,例如,来自main的行为显然与main的层次结构不同。它们都是根记录器在不同分支上的后代。

最后一项确实是你问题的答案。如果希望程序中的所有记录器共享相同的默认日志记录方法,则应配置根记录器,或确保它们具有相同的名称前缀,然后将其配置为根日志记录器。

您可以让所有记录器从main继承。在module/module.py中,您可以

代码语言:javascript
运行
复制
logger = logging.getLogger('__main__.' + __name__)

这里的问题是名称__main__是硬编码的。您无法保证这将是__main__main。您可以尝试在import main中使用module,这样就可以执行main.__name__ + '.' + __name__,但这不能像预期的那样工作。如果main作为__main__运行,导入它实际上将创建第二个模块对象,该对象具有完全独立的日志层次结构。

这就是根记录器没有名称的原因。它提供了所需的可维护性和一致性。你不需要跳过圈试图找出根的名称。

尽管如此,您仍然应该将main.py日志记录到__main__main记录器。根记录器只应在导入保护中设置。这样,如果将main作为常规模块导入,它将尊重正在运行的驱动程序的日志记录设置。

TL;博士

传统的做法是在程序的驱动程序中设置匿名根记录器。不要试图从__main__或驱动程序模块名继承记录器。

票数 8
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/58188743

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档