如何使用StreamHandler捕获日志记录器的stderr输出?

4
将正常日志输出重定向是可行的:
import contextlib
import io
import logging

std_out_capture = io.StringIO()
with contextlib.redirect_stderr(std_out_capture):
    logging.error('Hi.')

output = std_out_capture.getvalue()
print(f'output: {output}')

输出:

output: ERROR:root:Hi.

然而,当使用logging.basicConfig更改日志格式时

import contextlib
import io
import logging

log_format = '[%(threadName)s] [%(levelname)s] %(message)s'
logging.basicConfig(format=log_format)

std_out_capture = io.StringIO()
with contextlib.redirect_stderr(std_out_capture):
    logging.error('Hi.')

output = std_out_capture.getvalue()
print(f'output: {output}')

输出结果为:

output: 
[MainThread] [ERROR] Hi.

所以输出不再被捕获。
我的猜测是这是因为 logging.basicConfig(**kwargs):通过创建具有默认格式化程序的StreamHandler并将其添加到根日志记录器,对日志系统进行基本配置。

(https://docs.python.org/3/library/logging.html#logging.basicConfig)

StreamHandler 在单独的线程中工作,因此其输出不会被捕获。

对于单元测试,我仍然希望能够捕获它。我该怎么做?

1个回答

3

您需要将日志配置信息放入with语句体中,这样StreamHandler就会使用修改后的stderr进行初始化:

import contextlib
import io
import logging

std_out_capture = io.StringIO()
with contextlib.redirect_stderr(std_out_capture):
    log_format = '[%(threadName)s] [%(levelname)s] %(message)s'
    logging.basicConfig(format=log_format)
    logging.error('Hi.')

output = std_out_capture.getvalue()
print(f'output: {output}')
# output: [MainThread] [ERROR] Hi.

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