Go の勉強がてら Google Cloud Logging を使ってみた。
以下の記事で触れられているログをリクエストログに紐づいて表示させられるようにもしてある。
gclog.go
package gclog
import (
"context"
"fmt"
"os"
"runtime"
"strconv"
"strings"
"time"
"cloud.google.com/go/logging"
"github.com/gin-gonic/gin"
mrpb "google.golang.org/genproto/googleapis/api/monitoredres"
logpb "google.golang.org/genproto/googleapis/logging/v2"
)
// 以下の三つは Context に入れるべきだが簡略化のためここに記載
var WhenBegin time.Time
var TraceID string
var SpanID string
func NewClient(ctx context.Context) (*logging.Client, *logging.Logger, error) {
projectID := "your project here." // FIXME
client, err := logging.NewClient(ctx, projectID)
if err != nil {
return client, nil, err
}
return client, client.Logger(projectID), err
}
func Log(ctx context.Context, logger *logging.Logger, severity logging.Severity, msg string) {
entry := logging.Entry{
Payload: msg,
Severity: severity,
Resource: &mrpb.MonitoredResource{
Type: "gae_app",
},
}
if TraceID != "" {
entry.Trace = TraceID
entry.SpanID = strconv.FormatInt(time.Now().UnixNano(), 10)[:16]
}
pc, file, line, ok := runtime.Caller(1)
if ok {
entry.SourceLocation = &logpb.LogEntrySourceLocation{
File: file,
Line: int64(line),
Function: runtime.FuncForPC(pc).Name(),
}
}
Logger.Log(entry)
}
func LogRequest(ctx *gin.Context, logger *logging.Logger, severity logging.Severity) {
entry := logging.Entry{
Severity: severity,
Resource: &mrpb.MonitoredResource{
Type: "gae_app",
},
HTTPRequest: &logging.HTTPRequest{
Request: ctx.Request,
Latency: time.Now().Sub(WhenBegin),
},
}
if TraceID != "" {
entry.Trace = TraceID
entry.SpanID = SpanID
}
pc, file, line, ok := runtime.Caller(1)
if ok {
entry.SourceLocation = &logpb.LogEntrySourceLocation{
File: file,
Line: int64(line),
Function: runtime.FuncForPC(pc).Name(),
}
}
logger.Log(entry)
}
func Begin(ctx *gin.Context) {
WhenBegin = time.Now()
split := strings.Split(ctx.GetHeader("X-Cloud-Trace-Context"), "/")
if len(split) >= 2 {
TraceID = split[0]
split = strings.Split(split[1], ";")
SpanID = split[0]
}
}
func End(ctx *gin.Context) {
LogRequest(ctx, logging.Info)
}