1

我正在使用带有 Python 的谷歌云函数。我想用一些额外的数据格式化所有日志,例如客户 ID。我使用 Stackdriver Logging 库和CloudLoggingHandler. 同样,我也喜欢将此信息添加到未捕获的错误日志和回溯中。

我试图修改sys.excepthooksys.stderr但没有奏效,可能它们是由云功能专门处理的。

有什么方法可以修改未捕获的异常或修改已处理的错误,例如使用 Stackdriver 错误报告?或者您对此有任何替代解决方案(不捕获所有异常)?

4

2 回答 2

2

Cloud Functions 为代码执行提供(当前)最高级别的抽象。理念是您带来实现所需逻辑的代码,Cloud Functions 提供最高级别的执行环境。这有利有弊。

此外,最大的好处是,为了获得您想要的执行,您几乎不需要关心自己。

另一方面,您几乎没有操作控制的方式(愿景是 Cloud Functions 提供最大的操作控制)。

因此,如果您想以不得不做更多“工作”为代价对环境进行更多控制,我建议您使用 Cloud Run。在 Cloud Run 中,您将应用程序逻辑打包为 Docker 容器,然后要求它负责此类逻辑的所有执行。在您的容器中,您可以做任何您想做的事情……包括使用 Stackdriver 日志记录和定义 CloudLoggingHandler 等技术。然后,Cloud Run 会从那里处理您的扩展和执行环境。

总而言之,答案变为“否”,您无法控制 Cloud Functions 中的错误日志,但您可以通过利用 Cloud Run 来实现您想要的结果。

于 2019-11-24T22:46:27.183 回答
1

尽管您不能覆盖 sys.excepthook,但您可以执行以下操作:

为了提供一点上下文,我组织了类似于此处介绍的代码结构:https ://code.luasoftware.com/tutorials/google-cloud-functions/structure-for-google-cloud-functions-development-and-拆分多个文件/

Google 将您的函数入口点函数存储在一个名为X_GOOGLE_ENTRY_POINT. 您使用 Python 语言功能来覆盖此函数并将其包装为类似于“装饰器”,基本上将其包装在 try/except 块周围,然后您可以在那里运行您想要的任何代码。我尝试使用sys.modules[\__name__]但它没有用,所以我去了locals().

我在 test_logging.py 中定义了功能代码

from app.functions.test_logging import *

导入后我执行以下操作

fn = os.getenv('X_GOOGLE_ENTRY_POINT')
lcl = locals()
def decorate(fn):
    def run(*args, **kwargs):
        try:
            fn(*args, **kwargs)
        except Exception as e:
            '''Do whatever you want to do here'''
    return run

lcl[fn] = decorate(lcl[fn])

这很 hackish,但它对我有用,而且特别有用,因为我将代码库保存在函数文件夹中,我基本上不需要接触 main.py,这使得它非常灵活。如果您想让 GCP 知道它已失败并可能重新运行,您可以在处理异常后重新引发错误

于 2020-05-13T23:22:16.403 回答