在包模块中高效设置日志记录的方法

13 投票
2 回答
7062 浏览
提问于 2025-04-16 01:56

我有一个软件包,里面有几个组件,如果能使用日志记录功能并输出一些有用的信息,会大大提高它们的效果。

我不想为每一个文件都去“设置”合适的日志记录,像下面这样:

import logging
logging.basicConfig(level=DEBUG)
my_function = logging.getLogger("my_function")
my_class = logging.getLogger("my_class")

我尝试过几种方法,其中一种是把一些基础代码放到一个工具模块里的类里面,然后试着这样做:

from util import setlogging
set_logging()

但即使是上面的解决方案在我看来也不够简洁,而且会出现问题,因为 setLogger 没有 __call__ 方法。我喜欢的是我的“set_logging”类可以从配置文件中读取,并且有一些默认值,这样无论我想要什么级别或类型的日志格式,它都能正确设置。

有没有办法在我的整个软件包中初始化合适的日志记录?也许可以在 __init__.py 文件里?

为了尽量详细,这就是 setlogging(现在是一个函数,不是类)的样子:

def setlogging(config=None):
    if config == None:
        config = config_options() # sets default values
    levels = {
        'debug': DEBUG,
       'info': INFO
        }

    level = levels.get(config['log_level'])
    log_format = config['log_format']
    datefmt = config['log_datefmt']

    basicConfig(
        level   = level,
        format  = log_format,
        datefmt = datefmt)

2 个回答

1

一个模块正确使用日志记录的方法是

import logging
logger = logging.getLogger('my_module_name')

而且

logger.debug('help!')

在有人调用 logging.basicConfig()(或者类似的函数)之前,这些日志记录的操作不会有任何效果。

13

如果你想让你包里的所有模块都使用同一个日志记录器(logger),你只需要确保这个日志记录器是可用的,然后调用

mylogger.warning("Attenzione!")

或者类似的方式,而不是直接用 logging.warning 等等。这样,问题就变成了要为整个包创建一个 mylogger 对象,并确保它在包的所有模块中都能使用。(另外,你也可以使用以包名开头的命名日志记录器,后面加一个点,但虽然这也是 logging 包的一部分功能,我个人觉得这样操作不太自然)。

所以,你的 util.setlogging 函数后面可以简单地跟上,比如说,

mylogger = logging.getLogger(package_name)

然后每个导入了 util 的模块都可以直接使用

util.mylogger.warning('Watch out!')

以及类似的方式。对我来说,这似乎是最简单的方法,只要包里的所有代码都应该以相同的方式进行日志记录这个概念成立。

撰写回答