【问题标题】:Python logging in modules not working as expected模块中的 Python 日志记录未按预期工作
【发布时间】:2022-01-09 19:22:24
【问题描述】:

我确定我只是误解了它的工作原理,但我似乎无法将日志格式传播到登录模块,除非模块“知道”调用它的模块的名称。

以下代码演示了该问题。下面的代码有效,但我必须硬编码调用它的模块的名称才能应用格式。

app.py

import logging
import mymodule

logger = logging.getLogger('app')
log_formatter = logging.Formatter(f'%(asctime)s %(name)s[%(process)d]: %(levelname)s - %(message)s\n')
log_handler_console = logging.StreamHandler()
log_handler_console.setFormatter(log_formatter)
log_handler_console.terminator = ''
logger.addHandler(log_handler_console)

logger.error('testing 1')
mymodule.dosomething()

模块.py

import logging
logger = logging.getLogger('app.module')
def dosomething():
    logger.error('testing 2')

根据上面的代码,我得到了这个:

2022-01-09 19:01:53,986 app[46541]: ERROR - testing 1
2022-01-09 19:01:53,987 app.module[46541]: ERROR - testing 2

但如果我将记录器的名称更改为例如“测试”,我会得到:

2022-01-09 19:21:07,590 app[46580]: ERROR - testing 1
testing 2

如果我将 module.py 的第 2 行中的记录器名称更改为“app”或“app.something”以外的任何名称,则格式将不再适用。我知道继承是如何工作的(我认为),但是我怎么能知道调用模块的名称而不用硬编码呢?我确实在这里看到了一些关于 SO 的示例,但请注意这是一个坏主意。

基本上我要做的是在主应用程序中定义日志格式,并让主应用程序调用的任何模块使用相同的格式。我疯了吗?似乎很明显想要什么?

【问题讨论】:

    标签: python logging


    【解决方案1】:

    实际上,当我仍在试图弄清楚这一点时,我已经为自己找到了答案。我认为我会为遇到此问题的其他人回答问题,而不是删除问题。

    替换

    的两个实例(即在主应用程序和模块中)
    logger = logging.getLogger('something')
    

    logger = logging.getLogger()
    

    创建了一个“根”记录器,一切正常。

    【讨论】:

      【解决方案2】:

      您所期望的,“基本上我要做的是在主应用程序中定义一种日志格式,并让主应用程序调用的任何模块都使用相同的格式。”,这是完全合理的。

      “我怎样才能知道调用模块的名称而不用硬编码呢?” 您可以使用下面的代码来设置类似于 Python 包层次结构的记录器名称层次结构。

      logger = logging.getLogger(__name__)
      

      在所有子记录器默认启用传播的情况下,所有过滤的消息将通过层次结构向上传播,最后传播到根记录器,然后由其处理程序以指定的格式处理。

      有关使用 Python 日志记录的这些做法的更详细说明,您可以参考Good Practices of using Python Logging

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-03-22
        • 2018-11-04
        • 1970-01-01
        • 1970-01-01
        • 2017-06-04
        • 2020-05-31
        相关资源
        最近更新 更多