简体   繁体   English

Python 登录模块未按预期工作

[英]Python logging in modules not working as expected

I am sure I am just misunderstanding how this works but I cannot seem to have log formatting propagate to logging in modules unless the module "knows" the name of the module that called it.我确信我只是误解了它是如何工作的,但我似乎无法将日志格式传播到登录模块,除非模块“知道”调用它的模块的名称。

The following code demonstrates the issue.下面的代码演示了这个问题。 The code below works but I have to hard code the name of the module that called it for the formatting to apply.下面的代码有效,但我必须对调用它的模块的名称进行硬编码才能应用格式。

app.py应用程序.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()

module.py模块.py

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

As per code above I get this:根据上面的代码,我得到了这个:

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

but if I change the name of the logger to eg 'test' I get:但是如果我将记录器的名称更改为例如“测试”,我会得到:

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

If I change the name of the logger in line 2 of module.py to anything other than 'app' or 'app.something' then the formatting no longer applies.如果我将 module.py 第 2 行中的记录器名称更改为“app”或“app.something”以外的任何名称,则格式不再适用。 I get how the inheritance works (I think) but how can I know the calling module name without hard coding it?我知道 inheritance 是如何工作的(我认为)但是我怎么能在不硬编码的情况下知道调用模块的名称呢? I did see a few examples here on SO but with cautions that its a bad idea.我确实在这里看到了一些关于 SO 的例子,但警告说这是一个坏主意。

Essentially what I am trying to do is define a log format in the main app and have any module that the main app calls use the same format.本质上,我想做的是在主应用程序中定义日志格式,并让主应用程序调用的任何模块都使用相同的格式。 I am I crazy?我疯了吗? Seems like an obvious thing to want?似乎是一件显而易见的事情?

What you expect, "Essentially what I am trying to do is define a log format in the main app and have any module that the main app calls use the same format.", is totally reasonable.您所期望的,“本质上我想做的是在主应用程序中定义日志格式,并让主应用程序调用的任何模块都使用相同的格式。”,是完全合理的。

"how can I know the calling module name without hard coding it?" “我怎么能在不硬编码的情况下知道调用模块的名称呢?” You can use the below code to set up logger name hierarchy analogous to your Python package hierarchy.您可以使用以下代码设置类似于 Python package 层次结构的记录器名称层次结构。

logger = logging.getLogger(__name__)

With propagation enabled by default on all children loggers, all filtered messages will be propagated up through the hierarchical structure, and finally to the root logger, and then handled by its handler in its specified format.默认情况下在所有子记录器上启用传播,所有过滤的消息将通过层次结构向上传播,最后传播到根记录器,然后由其处理程序以其指定格式处理。

For more detailed explanation of those practices of using Python logging, you may refer to Good Practices of using Python Logging关于使用Python logging的那些做法更详细的解释,可以参考Good Practices of using Python Logging

Actually, while I was still trying to figure this out I figured the answer for myself.实际上,当我仍在试图弄清楚这一点时,我已经为自己找到了答案。 Rather than delete the question I thought I would answer it for anyone else who comes across this issue.而不是删除这个问题,我想我会为遇到这个问题的其他人回答这个问题。

Replacing both instances (ie, in the main app and in the module) of替换两个实例(即,在主应用程序和模块中)

logger = logging.getLogger('something')

with

logger = logging.getLogger()

A 'root' logger is created and everything works as I was expecting.创建了一个“根”记录器,一切都按我的预期工作。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM