跨模块使用相同的日志记录级别进行日志记录

Dor*_*har 4 python logging

我对 Python 有点陌生,尤其是在多个文件中编写模块和函数,而不仅仅是原始脚本。

\n\n

我正在编写一个命令行应用程序,我想要一个函数(我称之为argpconf)来解析命令行参数并相应地设置日志级别。最重要的是,我希望在此函数中设置一次日志级别,并在创建记录器时以最小的开销在所有模块中设置相同的日志级别。此外,我希望能够在使用通用格式化程序时识别消息来自的模块:

\n\n
logging.Formatter("%(levelname)s : %(name)s : %(message)s")\n
Run Code Online (Sandbox Code Playgroud)\n\n

部分基于cookiecutter 模板,我创建了以下文件:

\n\n
\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 api\n\xe2\x94\x82\xc2\xa0\xc2\xa0 \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 __init__.py\n\xe2\x94\x82\xc2\xa0\xc2\xa0 \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 some_functionality.py\n\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 cli.py\n\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 core\n\xe2\x94\x82\xc2\xa0\xc2\xa0 \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 argpconf.py\n\xe2\x94\x82\xc2\xa0\xc2\xa0 \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 __init__.py\n\xe2\x94\x82\xc2\xa0\xc2\xa0 \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 logger.py\n\xe2\x94\x82\xc2\xa0\xc2\xa0 \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 __version__.py\n\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 __init__.py\n\xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 __main__.py\n
Run Code Online (Sandbox Code Playgroud)\n\n

core/logger.py有以下内容:

\n\n
from logging import Formatter, Logger as _Logger, NullHandler, StreamHandler\n\nclass Logger(_Logger):\n    def __init__(self, name=None):\n        super(Logger, self).__init__(name or __name__.split(".")[0])\n        self.addHandler(NullHandler())  # default to no output\n    def start(self, level="WARN", stream=None,\n              fmt="%(levelname)s : %(name)s : %(message)s"):\n        handler = StreamHandler(stream)\n        handler.setFormatter(Formatter(fmt))\n        self.addHandler(handler)\n        self.setLevel(level.upper())\n    def stop(self):\n        for handler in self.handlers[1:]:\n            # Remove everything but the NullHandler.\n            self.removeHandler(handler)\n\nlogger = Logger()\n
Run Code Online (Sandbox Code Playgroud)\n\n

与这些问题的答案中提出的想法相比:

\n\n\n\n

我真的很喜欢带有记录器的 cookiecutter 模板中采用的方法,因为它允许您拥有import logger一个logger对象,它的日志级别在所有模块中都是相同的。但是,我对此并不完全满意,因为在我的情况下,它argpconf.py是第一个启动的模块,logger因此来自所有模块的所有日志消息都被%(name)s替换为core,因为它是 \' argpconf.pys __name__.split(".")[0]

\n\n

我如何改进logger模块,以便它能够检测调用它的模块并使用模块打印日志消息,%(name)s甚至可能是打印它们的函数?

\n

Vin*_*jip 5

这种方法似乎使事情变得比实际需要的更加复杂。我意识到这来自您使用的 cookiecutter 模板,这只是我的意见,但该模板中采用的日志记录方法并不是我认为的最佳实践。你最了解你的用例,但如果我只想

有一个函数可以解析命令行参数并相应地设置日志级别。最重要的是,我希望在此函数中设置一次日志级别,并且在创建记录器时在所有模块中设置相同的开销,并以最小的开销。此外,我希望能够在使用通用格式化程序时识别消息来自的模块

那么最简单的方法是在主脚本中导入argparselogging处理命令行参数并相应地设置日志记录级别,调用basicConfig()(如 Brian M. Sheldon 的评论中建议的那样),然后根据命令行参数确定分派到应用程序端点。您使用的每个需要记录某些内容的模块只需要import logging然后logger = logging.getLogger(__name__)logger.debug(...)其他任何内容,无论该模块中需要什么。如果您坚持这一点,所有模块将自动使用设置的日志记录级别,并且如果您在参数中basicConfig()使用片段,那么您将在记录的消息中的该位置看到完整的模块名称,作为完全限定的点分名字(比如%(name)sformat=basicConfig()api.some_functionality)。与 cookiecutter 模板相比,这种方法在创建记录器方面的开销肯定会更少。

更新:我将用一个示例更新Python Logging Cookbook。现在,这里有一个仅包含代码的要点。