python - 跨模块使用相同的日志记录级别进行日志记录
问题描述
我对 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
是__name__.split(".")[0]
.
我该如何改进logger
模块,以便它检测调用它的模块并打印日志消息,模块作为%(name)s
打印它们的函数,甚至可能是打印它们的函数?
解决方案
这种方法似乎使事情变得比他们需要的更复杂。我意识到这来自您使用的 cookiecutter 模板,这只是我的意见,但在该模板中采用的日志记录方法并不是我认为的最佳实践。你最了解你的用例,但如果我只想
有一个函数可以解析命令行参数并相应地设置日志级别。最重要的是,我希望在此函数中设置一次日志级别,并且在创建记录器时以最小开销在所有模块中保持相同。此外,我希望能够在使用通用格式化程序时识别消息来自的模块
那么最简单的方法是在您的主脚本中导入argparse
并处理命令行参数并相应地设置日志记录级别,调用(如 Brian M. Sheldon 的评论中所建议的那样),然后根据命令行参数确定调度到您的应用程序端点。您使用的每个模块都需要记录一些内容,然后在该模块中需要的任何地方进行记录。如果你坚持这一点,所有模块将使用自动设置的日志记录级别,如果你在参数中使用片段,那么你将在记录的消息中看到完整的模块名称,作为完全限定的点名字(比如logging
basicConfig()
import logging
logger = logging.getLogger(__name__)
logger.debug(...)
basicConfig()
%(name)s
format=
basicConfig()
api.some_functionality
)。与 cookiecutter 模板相比,这种方法在创建记录器方面的开销肯定会更少。
更新:我将通过一个示例更新Python Logging Cookbook 。现在,这是一个只有代码的要点。
推荐阅读
- javascript - 将图像链接到动态创建的 jquery 元素的问题
- android - 动画片段中的视图
- c++ - 使用文件流插入数据时,Vector 内的值不详
- microsoft-teams - MS Teams 消息扩展 submitTask 因“未找到 v3 代理”错误而失败
- html - Video-js 标签自动播放 HLS 直播
- excel - 宏开始抛出下标超出范围消息
- powershell - 在 PowerShell 中添加 If / If Not 语句
- sql-server - 转换电话号码时将数据类型 nvarchar 转换为数字时出错
- android - 在 Firebase 数据库中创建数据
- hybris - 如何在运行时更改自定义后台扩展的小部件配置?