python - 使用 python logger 从非 python 第三方库捕获输出
问题描述
我编写了一个使用该logging
模块的 Python 包,并广泛使用了带有 Python 包装器的第三方 C++ 库。我已经能够将我自己的包中的消息打印到控制台,以及将它们写入文件(并且每个处理程序具有不同的日志记录级别)。但是,我想在我的日志文件中包含第三方库打印的消息,以便查看它们出现的顺序。这是我的 MWE:
import logging
# Assume no direct access to this function. (e.g. c++ library)
def third_party_function():
print("Inside of 'third_party_function'.")
def my_helper():
logger.debug("Inside of 'my_helper', before third party call.")
third_party_function()
logger.warning("Finished with third party call.")
root_logger = logging.getLogger()
root_logger.setLevel(logging.NOTSET)
logger = logging.getLogger("mylogger")
stream_handler = logging.StreamHandler()
stream_handler.setLevel(logging.WARNING)
file_handler = logging.FileHandler(filename="progress.out")
file_handler.setLevel(logging.NOTSET)
logger.addHandler(stream_handler)
logger.addHandler(file_handler)
my_helper()
就目前而言,屏幕的输出是:
Inside of 'third_party_function'.
Finished with third party call.
并且文件progress.out
包含
Inside of 'my_helper', before third party call.
Finished with third party call.
但是,所需 progress.out
的文件是
Inside of 'my_helper', before third party call.
Inside of 'third_party_function'.
Finished with third party call.
似乎没有属于这个第三方库的记录器,因为它不是用 Python 编写的。
我希望避免设置sys.stdout
到文件(如在此处找到),因为我希望保持一致并始终使用该logging
模块。同一个问题的另一个答案定义了一个自定义类,但这似乎仍然没有捕捉到第三方消息。
解决方案
您可以暂时将标准输出从您的 3rd 方函数重定向到记录器。
使用您链接的答案中的 StreamToLogger 类:Redirect Python 'print' output to Logger
def wrap_third_party_function():
stdout = sys.stdout # save for restoring afterwards
# redirect stdout to use a logger, with INFO level
sys.stdout = StreamToLogger(logging.getLogger("mylogger.thirdparty"), logging.INFO)
print("start third_party_function; stdout to log")
third_party_function()
sys.stdout = stdout # restore stdout
print("done third_party_function; stdout restored")
def my_helper():
logger.debug("Inside of 'my_helper', before third party call.")
wrap_third_party_function()
logger.warning("Finished with third party call.")
在控制台上,你会得到这个:
done third_party_function; stdout restored
Finished with third party call.
而progress.out 将有:
Inside of 'my_helper', before third party call.
start third_party_function; stdout to log
Inside of 'third_party_function'.
Finished with third party call.
添加格式化程序可以更容易地查看:
formatter = logging.Formatter("%(name)s %(levelname)-8s %(message)s")
stream_handler.setFormatter(formatter)
file_handler.setFormatter(formatter)
使用此配置,progress.out 显示:
mylogger DEBUG Inside of 'my_helper', before third party call.
mylogger.thirdparty INFO start third_party_function; stdout to log
mylogger.thirdparty INFO Inside of 'third_party_function'.
mylogger WARNING Finished with third party call.
推荐阅读
- c# - 发送消息时如何解决 Azure EventHub 中的 SocketExceptions
- git - git:撤消上次提交并返回当前版本
- amazon-web-services - 如何在 Media Temple DV 上设置 AWS 凭证
- graphics - 使用非线性缩放将浮点数映射到颜色
- visual-studio-code - 如何在 vscode 中隐藏编辑器组菜单
- javascript - JQuery SmartWizard - 显示步骤,但未启用
- typo3 - 容器 DDEV / Typo3 Windows 10 中缺少项目文件
- git - git 子模块更新 --recursive --remote
- javascript - 函数改变全局变量
- javascript - 复制 SVG 的树