-
Notifications
You must be signed in to change notification settings - Fork 0
/
format_gcloud.go
87 lines (76 loc) · 2.51 KB
/
format_gcloud.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
package zaphttp
import (
"fmt"
"net"
"net/http"
"strconv"
"go.opentelemetry.io/otel/trace"
"go.uber.org/zap"
"go.uber.org/zap/zapcore"
)
// gcloudHTTPRequest is the logging format used for HTTP requests for google cloud.
// See: https://cloud.google.com/logging/docs/reference/v2/rest/v2/LogEntry#HttpRequest
type gcloudHTTPRequest struct {
RequestMethod string
RequestURL string
RequestSize string
Status int
UserAgent string
RemoteIP string
ServerIP string
Referrer string
Latency string
Protocol string
}
func (h *gcloudHTTPRequest) MarshalLogObject(enc zapcore.ObjectEncoder) error {
enc.AddString("requestMethod", h.RequestMethod)
enc.AddString("requestUrl", h.RequestURL)
enc.AddString("requestSize", h.RequestSize)
enc.AddInt("status", h.Status)
enc.AddString("userAgent", h.UserAgent)
enc.AddString("remoteIp", h.RemoteIP)
enc.AddString("serverIp", h.ServerIP)
enc.AddString("referrer", h.Referrer)
enc.AddString("latency", h.Latency)
enc.AddString("protocol", h.Protocol)
return nil
}
type gcloudFormatter struct {
projectID string
}
// Do not provide a default instance since we need the GCP project ID for fields like the full trace ID.
var _ Formatter = &gcloudFormatter{}
// NewGoogleCloudFormatter returns a log field formatter that will log HTTP requests and traces in a Google cloud
// compatible format.
func NewGoogleCloudFormatter(projectID string) Formatter {
return &gcloudFormatter{projectID: projectID}
}
func (f *gcloudFormatter) GetTraceFields(_ *http.Request, spanCtx trace.SpanContext) []zap.Field {
traceID := fmt.Sprintf("projects/%s/traces/%s", f.projectID, spanCtx.TraceID().String())
return []zap.Field{
zap.String("trace", traceID),
zap.String("spanId", spanCtx.SpanID().String()),
zap.Bool("traceSampled", spanCtx.IsSampled()),
}
}
func (f *gcloudFormatter) GetRequestFields(req *http.Request, res *ResponseInfo) []zap.Field {
var serverIP string
if localAddr, ok := req.Context().Value(http.LocalAddrContextKey).(net.Addr); ok {
serverIP = localAddr.String()
}
h := &gcloudHTTPRequest{
RequestMethod: req.Method,
RequestURL: req.URL.Redacted(),
RequestSize: strconv.FormatInt(req.ContentLength, 10),
Status: res.StatusCode,
UserAgent: req.UserAgent(),
RemoteIP: req.RemoteAddr,
ServerIP: serverIP,
Referrer: req.Referer(),
Latency: strconv.FormatFloat(res.Latency.Seconds(), 'f', -1, 64) + "s",
Protocol: req.Proto,
}
return []zap.Field{
zap.Object("httpRequest", h),
}
}