【问题标题】:Logging from a child module ignores the added root logger stream handler从子模块记录会忽略添加的根记录器流处理程序
【发布时间】:2016-06-28 22:33:58
【问题描述】:

我的目标是将日志消息从某个函数重定向到一个文件中。该函数在另一个模块中定义。我将 StreamHandler 添加到主记录器,但来自 child_call 函数的消息未按预期保存到 tmp.log

# main.py

import logging
import os
import sys
from child_logger import child_call

logging.basicConfig(format='%(name)s:%(filename)s:%(lineno)d:%(message)s', 
      level=logging.INFO, stream=sys.stdout)

logger = logging.getLogger(__name__)
logger.info('here it is')

with open('tmp.log', 'w') as f:
    logger_stream_handler = logging.StreamHandler(stream=f)
    logger_stream_handler.setLevel(logging.INFO)

    logger.addHandler(logger_stream_handler)
    logger.info('I am outer')
    child_call()
    logger.removeHandler(logger_stream_handler)


# child_logger.py

import logging
logger = logging.getLogger(__name__)

def child_call():
    logger.info('I am inner')

这是输出:

%python logger_test.py                                                
__main__:logger_test.py:18:here it is                                                                                                                                                
__main__:logger_test.py:25:I am outer                                                                                                                                          
child_logger:child_logger.py:9:I am inner

%cat tmp.log  
I am outer

我希望在 tmp.log 中看到“我很内向”。据我了解日志记录模块,创建了 Logger 对象的层次结构,默认情况下来自子级的消息应传播到根 Logger,并且根应处理所有消息。我错过了什么?

【问题讨论】:

    标签: python logging


    【解决方案1】:

    问题在于您的记录器未正确链接。它们需要具有相同的根名称。例如:

    # main.py
    logger = logging.getLogger("parent")
    
    # child_logger.py
    logger = logging.getLogger("parent.child")
    

    您的两个日志检索都只要求一个带有__name__ 的记录器,它被设置为模块的名称,除了顶级,它得到“__main__”。你最终得到的结果是这样的:

    # main.py
    logger = logging.getLogger("__main__")
    
    # child_logger.py
    logger = logging.getLogger("child_logger")
    

    您需要强制使用通用父日志记录名称方案来创建正确的记录器继承层次结构。

    【讨论】:

    • 谢谢!我认为日志记录会考虑模块层次结构并在内部调整记录器名称以构建相应的层次结构。
    • 你知道如何强制 child_logger 使用我想要的处理程序吗?我无法更改第三方模块 child_logger.py,同时我不想在 getLogger 调用中明确使用模块名称。也许有一种方法可以获取包含所有可用 Logger 的可迭代对象,然后为它们中的每一个分配一个处理程序?
    • @SergiusBond 不幸的是我没有。仔细查看日志模块文档,了解可能对您有所帮助的功能。如果您没有找到任何内容,请考虑打开一个新问题(在搜索重复项之后)。
    猜你喜欢
    • 2018-09-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多