/
logger.go
150 lines (123 loc) · 3.46 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
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
package log
import (
"fmt"
"io"
"os"
"go.uber.org/zap"
"go.uber.org/zap/zapcore"
)
// Pattern sourced from here: https://stackoverflow.com/questions/30257622/golang-zap-how-to-do-a-centralized-configuration
var (
output io.Writer = os.Stdout
logger *zap.Logger
envLogLevel = "LOG_LEVEL"
defaultLogLevel = zap.WarnLevel
atomicLevel zap.AtomicLevel
)
// Level of logging
type Level = zapcore.Level
const (
// DebugLevel logs are typically voluminous, and are usually disabled in
// production.
DebugLevel Level = zapcore.DebugLevel
// InfoLevel is the default logging priority.
InfoLevel Level = zapcore.InfoLevel
// WarnLevel logs are more important than Info, but don't need individual
// human review.
WarnLevel Level = zapcore.WarnLevel
// ErrorLevel logs are high-priority. If an application is running smoothly,
// it shouldn't generate any error-level logs.
ErrorLevel Level = zapcore.ErrorLevel
// DPanicLevel logs are particularly important errors. In development the
// logger panics after writing the message.
DPanicLevel Level = zapcore.DPanicLevel
// PanicLevel logs a message, then panics.
PanicLevel Level = zapcore.PanicLevel
// FatalLevel logs a message, then calls os.Exit(1).
FatalLevel Level = zapcore.FatalLevel
_minLevel = DebugLevel
_maxLevel = FatalLevel
)
// Field represents the key-value pair for logging
type Field = zap.Field
// WriteSyncer represents a writer than support syncing.
type WriteSyncer = zapcore.WriteSyncer
func init() {
var (
envLevel string
level zapcore.Level
ok bool
err error
)
if envLevel, ok = os.LookupEnv(envLogLevel); !ok {
level = defaultLogLevel
} else if err = level.UnmarshalText([]byte(envLevel)); err != nil {
_ = fmt.Errorf("parsing error %s %w", envLogLevel, err)
level = defaultLogLevel
}
atomicLevel = zap.NewAtomicLevelAt(level)
encoderCfg := zap.NewProductionEncoderConfig()
encoderCfg.EncodeLevel = zapcore.CapitalColorLevelEncoder
encoderCfg.TimeKey = ""
options := []zap.Option{
zap.AddCaller(),
zap.AddCallerSkip(1),
}
// show stacktrace
options = append(options, zap.AddStacktrace(zap.WarnLevel))
logger = zap.New(
zapcore.NewCore(
zapcore.NewConsoleEncoder(encoderCfg),
zapcore.Lock(zapcore.AddSync(output)),
atomicLevel,
),
options...,
)
}
// SetWriteSyncer sets the underlying logger
func SetWriteSyncer(out io.Writer) {
output = out
}
// SetLevel calls SetLevel on the underlying logger
func SetLevel(level Level) {
atomicLevel.SetLevel(level)
}
func GetLevel() Level {
return atomicLevel.Level()
}
// Sync calls Sync on the underlying logger
func Sync() {
logger.Sync()
}
// Debug logs error messages
func Debug(msg string, fields ...Field) {
logger.Debug(msg, fields...)
}
// Info logs error messages
func Info(msg string, fields ...Field) {
logger.Info(msg, fields...)
}
// Warn logs error messages
func Warn(msg string, fields ...Field) {
logger.Warn(msg, fields...)
}
// Error logs error messages
func Error(msg string, fields ...Field) {
logger.Error(msg, fields...)
}
// Fatal logs error messages
func Fatal(msg string, fields ...Field) {
logger.Fatal(msg, fields...)
}
// Panic logs error messages
func Panic(msg string, fields ...Field) {
logger.Panic(msg, fields...)
}
// writeSyncer decorates an io.Writer with a no-op Sync() function.
type writeSyncer struct {
io.Writer
}
// Sync does nothing since all output was written to the writer immediately.
func (ws writeSyncer) Sync() error {
return nil
}