【问题标题】:Logs from GCF in Go doesn't contains log levelGo 中来自 GCF 的日志不包含日志级别
【发布时间】:2019-12-13 23:25:34
【问题描述】:

我正在尝试从用 Go 编写的 Cloud Function 将信息/错误日志发送到 StackDriver Logging on GCP,但是所有日志都没有日志级别分配。

我从https://github.com/GoogleCloudPlatform/golang-samples/blob/master/functions/helloworld/hello_logging.go 创建了函数 演示问题。

【问题讨论】:

    标签: go google-cloud-functions google-cloud-logging


    【解决方案1】:

    云支持在这里!正如documentation 中所指定的那样,您尝试做的事情是不可能的:

    • stdoutstderr 的日志没有关联的日志级别。

    • 内部系统消息具有 DEBUG 日志级别。

    您可能需要使用Logging API,特别是Log Levels 部分。

    如果这对您不起作用,您也可以尝试使用node.js 而不是go,因为currently emits logsINFOERROR 级别分别使用console.log()console.error()

    【讨论】:

    • 我曾尝试使用该库,但无法使其正常工作。它没有返回任何错误,但没有任何内容记录到 stackdriver。
    • 您好@nephe 我已经修改了我的答案,为您提供了另一种可能的解决方案。我还希望您运行此命令:gcloud functions logs read FUNCTION_NAME,并验证您是否可以在其中看到日志。
    • 我试过了,它也返回没有任何级别的日志,只返回标准记录器生成的日志,而不是你排列的日志。您能否将我链接到我可以监控何时将此类支持添加到 Go 中的 GCF 的问题?
    • 我发现了this 公共问题,要求对 GCF 实施日志记录严重性。此外,我还创建了 this 问题,专门要求在 Go 中记录 GCF 的严重性。
    【解决方案2】:

    Go 1.13 运行时不再设置我以前的工作方法所需的环境变量。

    创建了一个采用不同方法的新库: github.com/ncruces/go-gcp/glog

    从好的方面来说,新版本与 Google Cloud Run 兼容。它也适用于 Go 1.11 运行时。

    用法:

    func HelloWorld(w http.ResponseWriter, r *http.Request) {
        glog.Infoln("Hello logs")
        glog.Errorln("Hello logs")
    }
    

    上一个答案

    欢迎您使用以下库: github.com/ncruces/go-gcf/logging

    支持日志级别,执行 ID 也是如此。

    用法:

    func HelloWorld(w http.ResponseWriter, r *http.Request) {
        ctx := logging.ForRequest(r)
        // ...
        logging.Info(ctx).Println("Hello logs")
        logging.Error(ctx).Println("Hello logs")
    }
    

    或者,对于后台功能:

    func HelloBackground(ctx context.Context, m interface{}) error {
        logging.Info(ctx).Println("Hello logs")
        logging.Error(ctx).Println("Hello logs")
        return nil
    }
    

    完全披露:我是作者。 我已经在生产中使用它 6 个月了。 非常感谢您的反馈。

    【讨论】:

    • 谢谢,它看起来工作正常并且正在设置有效的错误级别。
    • 嗨,我想知道我应该给我的函数什么权限,以便他们可以使用 API。我目前在尝试在我的代码中使用时收到权限错误
    【解决方案3】:

    您可以使用允许您设置日志级别的外部库。 Here 我使用的一个例子。 使用 logrus 设置最小日志级别(您可以通过在 env var 中提供日志级别来改进此代码)和 joonix 用于 fluentd 格式化程序。(第 25 行)

    注意点。第11行,我重命名logrus包日志 log "github.com/sirupsen/logrus" 因此,不要使用 log 标准库,而是使用 logrus 库。有时很无聊...您可以简单地将 log 替换为 logrus 以避免所有混乱。

    Joonix 是一个 fluentD 格式化程序,用于将日志转换为 Stackdriver 的可提取格式。

    【讨论】:

    • 我已尝试使用您提供的格式化程序,但它的行为仍然无效。一切都添加为文本有效负载textPayload: "{"httpRequest":{"requestMethod":"POST","status":200,"responseSize":"31337","userAgent":"Go-http-client/1.1","latency":{"nanos":123000000}},"message":"additional info","severity":"INFO","timestamp":{"seconds":1565175967,"nanos":261743604}}"
    • 是的,有一件棘手的事情。看第11行log "github.com/sirupsen/logrus"我把logrus包重命名为log。然后我使用 log.debugf(...) 登录调试级别。格式化程序仅将输出转换为 fluentD 格式,以便堆栈驱动程序摄取不稳定。
    • 我不确定我是否理解你。我使用 los 作为github.com/sirupsen/logrus。然后我将格式化程序设置为joonix,并将级别设置为Debug。但是,它仍然会在 stackdriver 中作为文本有效负载。
    • 你是对的。这适用于 Cloud Run 和 GCE/GKE,但不适用于 Cloud Function。我使用不同的记录器配置进行了一些测试。我不明白有什么不同以及为什么它不起作用。
    【解决方案4】:

    我也尝试为此创建一个包。如果您使用 logrus (https://github.com/sirupsen/logrus),那么这可能会有所帮助:

    https://github.com/tekkamanendless/gcfhook

    我在生产中使用它,它工作得很好。

    【讨论】:

      【解决方案5】:

      我推荐https://github.com/apsystole/log。它也是 log 和 logrus 兼容的,但是一个小的 zero-dependency 模块与两个现有答案中使用的库不同,它们将 400 多个模块作为它们的依赖项(喘气......我只是在看@ 987654322@).

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2023-02-17
        • 1970-01-01
        • 2015-06-23
        • 2012-08-18
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-05-13
        相关资源
        最近更新 更多