如何使用 Python 在日志文件中复制/捕获标准输出

Posted

技术标签:

【中文标题】如何使用 Python 在日志文件中复制/捕获标准输出【英文标题】:How to Duplicate/Capture Stdout in Log File with Python 【发布时间】:2020-05-20 19:38:22 【问题描述】:

我在 Python 设置中有一个基本的记录器处理程序来记录到文件。我希望这个日志处理程序记录通常会打印到控制台的任何/所有标准输出或标准错误消息,但我不想重定向或捕获它。换句话说,我仍然希望一切都以通常的方式打印。

这里的用例是我不想将应用程序中的每个命令都用

try:
    do_something_that_could_raise_exception()
except Exception as e:
    logger.exception(e)

相反,我只想让应用程序运行,并能够查看日志文件以查看遇到的任何错误的堆栈跟踪。我只希望所有的 stdout/stderr 消息出现在我的日志文件中。

这似乎是对 SO 上多次被问到的主题的转折。我读过Logging Python stdout to File... with active stdout (backspacing/updating)、Redirect stdout to a file in Python? 和许多其他的,但这些似乎并没有解决我的情况。我见过的所有问题都在谈论如何使用多个处理程序同时打印到日志和标准输出,或者如何将标准输出重定向到日志以便终端中不显示任何内容。

编辑

为后代编辑。经过一番搜索后,我找到了https://code.tutsplus.com/tutorials/professional-error-handling-with-python--cms-25950,它演示了如何添加一个函数装饰器,将异常定向到给定的日志处理程序。这并不像我希望的那么简洁(因为我仍然必须将函数装饰器添加到我所有的函数定义中),但它比将我的所有函数调用包装在 try-except 中要简单得多。

def log_error(logger)

    def decorated(f):
        @functools.wraps(f)
        def wrapped(*args, **kwargs):
            try:
                return f(*args, **kwargs)
            except Exception as e:
                if logger:
                    logger.exception(e)
                raise
        return wrapped

    return decorated

Here is how to use it:
01
02
03
04
05
06
07
08
09
10
11

import logging
logger = logging.getLogger()

@log_error(logger)
def f():
    raise Exception('I am exceptional')

【问题讨论】:

【参考方案1】:

由于您似乎只对异常感兴趣,因此您可以使用 sys.excepthook 而不是该包装器,如下所述:Logging uncaught exceptions in Python

这样它只需要定义一次,并且在定义新函数时不会忘记它。

【讨论】:

以上是关于如何使用 Python 在日志文件中复制/捕获标准输出的主要内容,如果未能解决你的问题,请参考以下文章

如何在 JavaScript 中捕获右键单击事件? [复制]

每当有人尝试从 Python 中的特定文件夹复制任何文件时如何记录日志

是否可以使用标准输出作为流利的源来捕获特定日志以写入弹性搜索?

如何使用 python 正则表达式替换使用捕获的组? [复制]

从子进程中实时捕获标准输出

如何在调用 python 脚本时捕获 python 脚本的结果? [复制]