【发布时间】:2019-08-08 00:54:01
【问题描述】:
我正在使用带有 Go 1.11 运行时的 Google App Engine 标准环境。 Go 1.11 的文档说“使用 stdout 编写应用程序日志作为输出,使用 stderr 编写错误”。 Go 1.9 指南的迁移还建议不要直接调用 Google Cloud Logging 库,而是通过 stdout 进行日志记录。 https://cloud.google.com/appengine/docs/standard/go111/writing-application-logs
考虑到这一点,我编写了一个小型 HTTP 服务(下面的代码)来试验使用 JSON 输出到标准输出来记录到 Stackdriver。
当我打印纯文本消息时,它们会按预期显示在 textPayload 下的“日志查看器”面板中。当我传递一个 JSON 字符串时,它们出现在jsonPayload 下。到目前为止,一切顺利。
所以,我在输出字符串中添加了一个severity 字段,Stackdriver Log Viewer 成功地根据分级日志通知、警告等对消息进行分类。
https://cloud.google.com/logging/docs/reference/v2/rest/v2/LogEntry
文档说设置trace 标识符以将日志条目与原始请求日志相关联。跟踪 ID 是从容器设置的 X-Cloud-Trace-Context 标头中提取的。
使用curl -v -H 'X-Cloud-Trace-Context: 1ad1e4f50427b51eadc9b36064d40cc2/8196282844182683029;o=1' http://localhost:8080/在本地模拟它
但是,这不会导致消息按请求线程化,而是trace 属性出现在日志的jsonPayload 对象中。 (见下文)。
请注意,severity 已按预期解释,并且未出现在 jsonPayload 中。我原以为trace 也会发生同样的情况,但它似乎未处理。
如何在原始请求日志消息中实现嵌套消息? (这必须在 Go 1.11 上使用 stdout 完成,因为我不希望直接使用 Google Cloud 日志记录包进行记录)。
GAE 究竟在做什么来解析我正在运行的进程中的标准输出流? (在 GCE 上的虚拟机设置指南中,有一些关于安装代理程序以充当 Stackdriver 日志记录的管道——这是 GAE 安装的吗?)
app.yaml 文件如下所示:
runtime: go111
handlers:
- url: /.*
script: auto
package main
import (
"fmt"
"log"
"net/http"
"os"
"strings"
)
var projectID = "glowing-market-234808"
func parseXCloudTraceContext(t string) (traceID, spanID, traceTrue string) {
slash := strings.Index(t, "/")
semi := strings.Index(t, ";")
equal := strings.Index(t, "=")
return t[0:slash], t[slash+1 : semi], t[equal+1:]
}
func sayHello(w http.ResponseWriter, r *http.Request) {
xTrace := r.Header.Get("X-Cloud-Trace-Context")
traceID, spanID, _ := parseXCloudTraceContext(xTrace)
trace := fmt.Sprintf("projects/%s/traces/%s", projectID, traceID)
warning := fmt.Sprintf(`{"trace":"%s","spanId":"%s", "severity":"WARNING","name":"Andy","age":45}`, trace, spanID)
fmt.Fprintf(os.Stdout, "%s\n", warning)
message := "Hello"
w.Write([]byte(message))
}
func main() {
http.HandleFunc("/", sayHello)
port := os.Getenv("PORT")
if port == "" {
port = "8080"
}
log.Fatal(http.ListenAndServe(fmt.Sprintf(":%s", port), nil))
}
日志查看器中显示的输出:
...,
jsonPayload: {
age: 45
name: "Andy"
spanId: "13076979521824861986"
trace: "projects/glowing-market-234808/traces/e880a38fb5f726216f94548a76a6e474"
},
severity: "WARNING",
...
【问题讨论】:
-
除了这个单线程测试示例之外,不要使用上面的 parseXCloudTraceContext() 函数。在生产中,x-cloud-trace-context 的 ;o=1 部分并不总是存在,导致它出现恐慌。
标签: google-app-engine go stackdriver google-cloud-stackdriver