我正在尝试在一个地方为多模块应用程序设置我的日志格式(和日志级别)。
我的应用程序结构是:
myapp/
|- __init__.py
|- __main__.py
\_ sub/
|- foo.py
我启动它: python -m myapp
我在 __init__.py
中设置了 logging 如下:
import logging
logger = logging.getLogger(__name__)
logger.setLevel(logging.DEBUG)
stream_handler = logging.StreamHandler()
stream_handler.setLevel(logging.DEBUG)
formatter = logging.Formatter('%(asctime)s %(levelname)s %(name)s %(message)s')
stream_handler.setFormatter(formatter)
logger.addHandler(stream_handler)
logger.info("Finished configuring logger()")
这是 __main__.py
:
from myapp import logger
import myapp.sub.foo
def func():
logger.info(f"Hello from {__name__}")
func()
和 sub/foo.py
:
from myapp import logger
logger.info(f"Hello from {__name__}")
但是当我运行应用程序时,“%(name)s”字段总是包含“myapp”,而不是与使用记录器的模块相关的 __name__
。
例如
➜ python3 -m myapp
2022-05-18 17:07:53,529 INFO myapp Finished configuring logger()
2022-05-18 17:07:53,529 INFO myapp Hello from myapp.sub.foo
2022-05-18 17:07:53,530 INFO myapp Hello from __main__
如何通过类似简单的设置将 __name__
value 放入日志输出?
回答1
代替
from myapp import logger
做就是了
logger = logging.getLogger(__name__)
在所有相关模块中。
更新以回应评论:我想你会发现这是因为 __main__
的处理方式不同 - 请参阅 https://docs.python.org/3/library/__main__.html#main-py-in-python-packages。您可以通过在每个模块的开头放置 print(__name__)
行来确认这一点。在结果输出中,
$ python -m myapp
myapp
2022-05-19 09:19:18,088 INFO myapp Finished configuring logger
__main__
myapp.sub.foo
2022-05-19 09:19:18,090 INFO myapp Hello from myapp.sub.foo
2022-05-19 09:19:18,090 INFO myapp Hello from __main__
您可以看到 myapp
包首先使用 myapp
(myapp/__init__.py
) 的 __name__
导入,然后使用 __main__
的 __name__
执行 myapp/__main__.py
,然后导入 myapp/sub/foo.py
myapp.sub.foo
的 __name__
。