...
1 package ctxzap
2
3 import (
4 "context"
5
6 "github.com/grpc-ecosystem/go-grpc-middleware/tags"
7 "go.uber.org/zap"
8 "go.uber.org/zap/zapcore"
9 )
10
11 type ctxMarker struct{}
12
13 type ctxLogger struct {
14 logger *zap.Logger
15 fields []zapcore.Field
16 }
17
18 var (
19 ctxMarkerKey = &ctxMarker{}
20 nullLogger = zap.NewNop()
21 )
22
23
24 func AddFields(ctx context.Context, fields ...zapcore.Field) {
25 l, ok := ctx.Value(ctxMarkerKey).(*ctxLogger)
26 if !ok || l == nil {
27 return
28 }
29 l.fields = append(l.fields, fields...)
30 }
31
32
33
34
35 func Extract(ctx context.Context) *zap.Logger {
36 l, ok := ctx.Value(ctxMarkerKey).(*ctxLogger)
37 if !ok || l == nil {
38 return nullLogger
39 }
40
41 fields := TagsToFields(ctx)
42
43 fields = append(fields, l.fields...)
44 return l.logger.With(fields...)
45 }
46
47
48 func TagsToFields(ctx context.Context) []zapcore.Field {
49 fields := []zapcore.Field{}
50 tags := grpc_ctxtags.Extract(ctx)
51 for k, v := range tags.Values() {
52 fields = append(fields, zap.Any(k, v))
53 }
54 return fields
55 }
56
57
58
59 func ToContext(ctx context.Context, logger *zap.Logger) context.Context {
60 l := &ctxLogger{
61 logger: logger,
62 }
63 return context.WithValue(ctx, ctxMarkerKey, l)
64 }
65
66
67
68 func Debug(ctx context.Context, msg string, fields ...zap.Field) {
69 Extract(ctx).WithOptions(zap.AddCallerSkip(1)).Debug(msg, fields...)
70 }
71
72
73
74 func Info(ctx context.Context, msg string, fields ...zap.Field) {
75 Extract(ctx).WithOptions(zap.AddCallerSkip(1)).Info(msg, fields...)
76 }
77
78
79
80 func Warn(ctx context.Context, msg string, fields ...zap.Field) {
81 Extract(ctx).WithOptions(zap.AddCallerSkip(1)).Warn(msg, fields...)
82 }
83
84
85
86 func Error(ctx context.Context, msg string, fields ...zap.Field) {
87 Extract(ctx).WithOptions(zap.AddCallerSkip(1)).Error(msg, fields...)
88 }
89
View as plain text