Я использую стандартную среду Google App Engine со средой выполнения Go 1.11. В документации для Go 1.11 говорится: «Записывайте журналы приложения, используя stdout для вывода и stderr для ошибок». В руководстве по переходу с Go 1.9 также предлагается не вызывать библиотеку Google Cloud Logging напрямую, а вместо этого вести журнал через стандартный вывод. https://cloud.google.com/appengine/docs/standard/go111/writing-application-logs
Имея это в виду, я написал небольшую службу HTTP (код ниже), чтобы поэкспериментировать с ведением журнала в Stackdriver с использованием вывода JSON на стандартный вывод.
Когда я печатаю текстовые сообщения, они отображаются должным образом на панели средства просмотра журналов в разделе textPayload
. Когда я передаю строку JSON, они появляются под jsonPayload
. Все идет нормально.
Итак, я добавил поле severity
в строку вывода, и Stackdriver Log Viewer успешно классифицирует сообщение в соответствии с УВЕДОМЛЕНИЕМ, ПРЕДУПРЕЖДЕНИЕМ и т. Д. https://cloud.google.com/logging/docs/reference/v2/rest/v2/LogEntry
В документации говорится, что нужно установить идентификатор trace
для сопоставления записей журнала с журналом исходящего запроса. Идентификатор трассировки извлекается из заголовка X-Cloud-Trace-Context
, установленного контейнером.
Имитируйте это локально, используя curl -v -H 'X-Cloud-Trace-Context: 1ad1e4f50427b51eadc9b36064d40cc2/8196282844182683029;o=1' http://localhost:8080/
Однако это не приводит к тому, что сообщения распределяются по запросу, а вместо этого свойство trace
появляется в объекте jsonPayload
в журналах. (См. ниже).
Обратите внимание, что severity
интерпретируется как ожидалось и не отображается в jsonPayload
. Я ожидал, что то же самое произойдет с trace
, но вместо этого он оказался необработанным.
Как я могу получить вложенные сообщения в исходное сообщение журнала запросов? (Это должно быть сделано с помощью stdout в Go 1.11, поскольку я не хочу входить в систему напрямую с помощью пакета ведения журнала Google Cloud).
Что именно делает GAE для синтаксического анализа потока stdout из моего запущенного процесса? (В руководстве по установке виртуальных машин на 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",
...