/
ctx.go
65 lines (53 loc) · 2.22 KB
/
ctx.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
package clzap
import (
"context"
"fmt"
"github.com/aws/aws-lambda-go/lambdacontext"
"go.opentelemetry.io/otel/trace"
"go.uber.org/zap"
)
// ctxKey holds the context key under which the logger will be stored.
type ctxKey string
// LoggerFromContext attempts to get a zap logger from the context. Returns nil and false if there is no logger
// in the context.
func LoggerFromContext(ctx context.Context) (*zap.Logger, bool) {
logs, ok := ctx.Value(ctxKey("clzap.logger")).(*zap.Logger)
return logs, ok
}
// LambdaRequestIDKey determines the logging key for the AWS request id from the lambda context.
var LambdaRequestIDKey = "requestId" //nolint:gochecknoglobals
// Log retrieves a zap logger from the context. If the optional fallback logger is provided this logger is returned
// when the context has no logger, else a no-op logger is returned. If the context also
// has tracing and or span information this will be logged by the logger automatically.
func Log(ctx context.Context, fbl ...*zap.Logger) *zap.Logger {
logs, ok := LoggerFromContext(ctx)
if !ok {
if len(fbl) > 0 {
logs = fbl[0]
} else {
logs = zap.NewNop()
}
}
// if span information is in the context, add it as a field to the logger
span := trace.SpanFromContext(ctx)
if span != nil && span.SpanContext().HasSpanID() {
logs = logs.With(zap.String("span_id", span.SpanContext().SpanID().String()))
}
// log the trace id in the xray format, and add it as a field to the logger
if span != nil && span.SpanContext().HasTraceID() {
tid := span.SpanContext().TraceID().String()
logs = logs.With(zap.String("trace_id", fmt.Sprintf("1-%s-%s", tid[:8], tid[8:])))
}
// if the lambda context is present we add a request id so logs lines follow JSON format for
// lambda application logs as documented here:
// https://docs.aws.amazon.com/lambda/latest/dg/monitoring-cloudwatchlogs.html#monitoring-cloudwatchlogs-advanced
lc, ok := lambdacontext.FromContext(ctx)
if ok {
logs = logs.With(zap.String(LambdaRequestIDKey, lc.AwsRequestID))
}
return logs
}
// WithLogger returns a context with the provided logger embedded.
func WithLogger(ctx context.Context, logs *zap.Logger) context.Context {
return context.WithValue(ctx, ctxKey("clzap.logger"), logs)
}