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

alf*_*eza 11 python logging module package

我有一个包含多个组件的包,这些组件将从使用日志记录和输出有用信息中受益匪浅.

我不想做的是为这些行中的某个地方的每个文件"设置"正确的日志记录:

import logging
logging.basicConfig(level=DEBUG)
my_function = logging.getLogger("my_function")
my_class = logging.getLogger("my_class")
Run Code Online (Sandbox Code Playgroud)

我尝试了几种方法,其中一种方法是将样板代码添加到实用程序模块中的类中,并尝试执行以下操作:

from util import setlogging
set_logging()
Run Code Online (Sandbox Code Playgroud)

但即使上面的解决方案看起来并不干净,也会导致问题,因为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)
Run Code Online (Sandbox Code Playgroud)

Ale*_*lli 12

如果您希望包的各个模块中的所有代码都使用相同的记录器对象,您只需要(使该记录器可用 - 请参阅稍后 - 和)调用

mylogger.warning("Attenzione!")
Run Code Online (Sandbox Code Playgroud)

等等,而不是logging.warning&c.因此,问题减少mylogger为为整个包制作一个对象并使其在包中的整个模块中可用.(或者,您可以使用名称记录器,其名称以包名称开头,后跟一个点,但虽然这是logging包功能的一部分,但我个人从未发现它是一种自然的操作方式).

所以,你的util.setlogging功能可以简单地跟着,比方说,

mylogger = logging.getLogger(package_name)
Run Code Online (Sandbox Code Playgroud)

并且每个导入的模块都util可以使用

util.mylogger.warning('Watch out!')
Run Code Online (Sandbox Code Playgroud)

等等.在我看来,这是最简单的方法,只要包中的所有代码都应以相同方式登录的概念适用.