使用通配符设置Python日志记录器级别

3

我正在大量使用Python线程,我的许多用例要求我在不同的记录器名称下记录单独的任务执行。

一个典型的代码示例如下:

def task(logger=logger):
    global_logger.info('Task executing')
    for item in [subtask(x) for x in range(100000)]:
        # While debugging, one would generally prefer to see these
        global_logger.debug('Task executed item {}'.format(item))
    global_logger.info('Task done')

def thread_task(task_index, logger=logger):
    task(logger=global_logger.getChild('main.task.{}'.format(task_index)))

def main():
    pool = Pool(10)
    for item in pool.map(thread_task, range(128))
        pass

Python日志模块中是否有任何标准方法可以让我一次性设置所有线程的日志级别?

在代码中,我想做的是:

# For all threads
logger.getChild('main.task.0').setLevel('INFO')
logger.getChild('main.task.1').setLevel('INFO')
logger.getChild('main.task.2').setLevel('INFO')

我应该注意到,我知道可以在task_thread内部设置级别。我的问题是想找出是否有更简单的方法来完成这个操作。

2个回答

3

由于日志记录器如果没有明确设置,则继承其父级的级别,因此您可以只执行例如:

root_name = global_logger.name
logging.getLogger(root_name + '.main.task').setLevel(logging.INFO)

这意味着所有子记录器都会继承该级别,除非为其中一个显式设置了级别。

请注意,除非您想要为不同的线程记录器附加不同的处理程序,否则每个线程都有一个记录器并没有太多好处 - 您可以始终使用其他方法将 task_index 值放入日志中。(参考)


你没有理解重点。这是一个简单的解决方案,但仍然是一种hack。如果我想要做以下操作怎么办: logging.getLogger('main.task.*.subtask_a').setLevel(logging.INFO) logging.getLogger('main.task.*.subtask_b').setLevel(logging.DEBUG) - Andrey Cizov
我现在看到了你的编辑。那样更有意义。 - Andrey Cizov

1

我遇到了同样的问题,无法抑制BAC0库的输出。我尝试更改父记录器,但未更新子记录器(Python 3.9)。

此答案基于此帖子中的已接受答案:如何使用python.logging模块列出所有现有记录器

for name in logging.root.manager.loggerDict:
    if name.startswith("main.task."):
        logging.getLogger(name).setLevel(logging.INFO)

你可以用一些正则表达式匹配通配符来替换name.startswith("main.task."),但这应该对你有所帮助。

它的作用是获取并迭代已配置的每个记录器,并检查名称是否与您的搜索条件匹配。如果匹配,则会按名称获取记录器,并将级别设置为INFO


1
我喜欢这个答案 - 虽然是一个hack,但它提供了一个解决方案。 - Andrey Cizov
这个技巧只适用于已经配置好的日志记录器。 - K3---rnc

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接