如何使用Nullhandler重定向外部模块的记录器警告



如果这个问题与SO上发布的其他问题类似,我深表歉意,但我已经尝试了许多给出的答案,但无法实现我想要做的。

我有一些代码可以调用外部模块:

import trafilatura
# after obtaining article_html
text = trafilatura.extract(article_html, language=en)

这有时会在控制台上打印出警告,该警告来自trafilatura模块中的以下代码:

# at the top of the file
LOGGER = logging.getLogger(__name__)
# in the method that I'm calling
LOGGER.warning('HTML lang detection failed')

我不想将该模块生成的这条消息和其他消息直接打印到控制台,而是将它们存储在某个地方,这样我就可以编辑消息并决定如何处理它们。(具体来说,我想以稍微修改过的形式保存消息,但只在特定情况下保存。(我在自己的代码中没有使用日志库。

我尝试了以下解决方案建议:

buf = io.StringIO()
with contextlib.redirect_stderr(buf):  # I also tried redirect_stdout
text = trafilatura.extract(article_html, language=en)

buf = io.StringIO()    
sysout = sys.stdout
syserr = sys.stderr
sys.stdout = sys.stderr = buf
text = trafilatura.extract(article_html, language=en)
sys.stdout = sysout
sys.stderr = syserr

然而,在这两种情况下,buf都保持为空,trafilatura仍然将其日志消息打印到控制台。用其他调用(例如print("test")(测试上面的重定向,它们似乎能很好地捕捉到这些重定向,所以显然trafilatura的LOGGER.warning()没有打印到stderr或stdout?

我以为我可以为trafilatura的LOGGER设置一个不同的输出流目标,但它使用了一个NullHandler,所以我既不能确定它的流目标,也不知道如何更改它:

# from trafilatura's top-level __init__.py
logging.getLogger(__name__).addHandler(NullHandler())

有什么想法吗?提前谢谢。

这里的想法是在python的标准日志库中工作。添加NullHandler实际上是添加记录器的库的标准推荐做法,因为如果没有日志记录配置,它可以防止返回到stderr。

这里可能发生的情况是,这些日志正在传播到根记录器,该记录器在其他地方附加了一些处理程序。您可以通过在代码中获取模块的记录器并将其设置为不传播来停止这种情况:

# assuming that "trafilatura" is the __name__ of the module:
logger = logging.getLogger("trafilatura")
logger.propagate = False

最新更新