繁体   English   中英

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

[英]logging with the same logging levels across modules

我是Python的新手,尤其是在多个文件中编写模块和函数,而不仅仅是原始脚本。

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

logging.Formatter("%(levelname)s : %(name)s : %(message)s")

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

├── api
│   ├── __init__.py
│   └── some_functionality.py
├── cli.py
├── core
│   ├── argpconf.py
│   ├── __init__.py
│   ├── logger.py
│   └── __version__.py
├── __init__.py
└── __main__.py

core/logger.py具有以下内容:

from logging import Formatter, Logger as _Logger, NullHandler, StreamHandler

class Logger(_Logger):
    def __init__(self, name=None):
        super(Logger, self).__init__(name or __name__.split(".")[0])
        self.addHandler(NullHandler())  # default to no output
    def start(self, level="WARN", stream=None,
              fmt="%(levelname)s : %(name)s : %(message)s"):
        handler = StreamHandler(stream)
        handler.setFormatter(Formatter(fmt))
        self.addHandler(handler)
        self.setLevel(level.upper())
    def stop(self):
        for handler in self.handlers[1:]:
            # Remove everything but the NullHandler.
            self.removeHandler(handler)

logger = Logger()

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

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

如何改善logger模块,使其能够检测到调用该模块的模块,并使用%(name)s甚至是打印它们的函数来打印日志消息?

这种方法似乎使事情变得比所需复杂。 我意识到这来自您使用的cookiecutter模板,这只是我的观点,但是在该模板中进行日志记录的方法并不是我认为的最佳实践。 您最了解用例,但是如果我想做的就是

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

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

更新:我将通过示例更新Python日志记录手册 现在, 这里是仅包含代码的要点

暂无
暂无

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

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