/
logger.go
120 lines (106 loc) · 3.49 KB
/
logger.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
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
package zapray
import (
"context"
"net/http"
"github.com/aws/aws-xray-sdk-go/xray"
"go.uber.org/zap"
"go.uber.org/zap/zapcore"
)
// AppVersion is exposed to allow build time versions to be set.
// go build -ldflags="-X 'github.com/joerdav/zapray.AppVersion.AppVersion=v1.0.0'"
var AppVersion = ""
// Logger is a wrapper for zap.Logger, exposes the zap.Logger functions and adds the ability to Trace logs.
type Logger struct {
*zap.Logger
SuppressMissingSegmentWarning bool
}
// NewLogger creates a new instance of *Logger and wraps the logger provided.
// z, _ := zap.NewProduction()
// log := zapray.NewLogger(z)
func NewLogger(zapLogger *zap.Logger) *Logger {
l := zapLogger
if AppVersion != "" {
l = zapLogger.With(zap.String("appVersion", AppVersion))
}
return &Logger{
Logger: l,
}
}
// New creates a new instance of zap.Logger and wraps it in a zapray.Logger
func New(core zapcore.Core, options ...zap.Option) *Logger {
return NewLogger(zap.New(core, options...))
}
// NewNop creates a new instance of *Logger and includes a zap.NewNop().
// log := zapray.NewNop()
func NewNop() *Logger {
return NewLogger(zap.NewNop())
}
// NewDevelopment creates a new instance of *Logger and includes a zap.NewDevelopment().
// log := zapray.NewDevelopment()
func NewDevelopment() (*Logger, error) {
logger, err := zap.NewDevelopment()
if err != nil {
return nil, err
}
return NewLogger(logger), nil
}
// NewProduction creates a new instance of *Logger and includes a zap.NewProduction().
// log := zapray.NewProduction()
func NewProduction() (*Logger, error) {
logger, err := zap.NewProduction()
if err != nil {
return nil, err
}
return NewLogger(logger), nil
}
// Trace creates a new zap.Logger but with the xrayTraceId and xraySegmentId baked in.
// log.Trace(ctx).Info("myLog")
//
// Once trace is called you can use it as a zap.Logger.
//
// tracedLogger := log.Trace(ctx)
// tracedLogger.Info("Log one")
// tracedLogger.Info("Log two")
//
// This means as above you can trace once and use the provided logger.
func (zprl *Logger) Trace(ctx context.Context) (res *Logger) {
logger := zprl.Logger
defer func() {
if r := recover(); r != nil {
if !zprl.SuppressMissingSegmentWarning {
zprl.Logger.Warn("no segment found")
}
res = zprl
}
}()
seg := xray.GetSegment(ctx)
traceId := seg.TraceID
segmentId := seg.ID
logger = zprl.Logger.With(zap.String("@xrayTraceId", traceId), zap.String("@xraySegmentId", segmentId))
return NewLogger(logger)
}
// TraceRequest creates a new zap.Logger but with the xrayTraceId and xraySegmentId baked in.
// log.TraceRequest(r).Info("myLog")
//
// Once trace is called you can use it as a zap.Logger.
//
// tracedLogger := log.Trace(r)
// tracedLogger.Info("Log one")
// tracedLogger.Info("Log two")
//
// This means as above you can trace once and use the provided logger.
func (zprl *Logger) TraceRequest(r *http.Request) *Logger {
return zprl.Trace(r.Context())
}
// WithOptions delegates to zap.Logger.WithOptions and wraps the resulting logger into a zapray.Logger
func (log *Logger) WithOptions(opts ...zap.Option) *Logger {
return NewLogger(log.Logger.WithOptions(opts...))
}
// With delegates to zap.Logger.With and wraps the resulting logger into a zapray.Logger
func (log *Logger) With(fields ...zap.Field) *Logger {
return NewLogger(log.Logger.With(fields...))
}
// Named delegates to zap.Logger.Named and wraps the resulting logger into a zapray.Logger
func (log *Logger) Named(s string) *Logger {
return NewLogger(log.Logger.Named(s))
}