/
logger.go
225 lines (187 loc) · 6.25 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
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
package logger
import (
"go.uber.org/zap"
"go.uber.org/zap/zapcore"
"os"
"strings"
)
type Config struct {
LogLevel string `env:"LOGGER_LEVEL" envDefault:"info"`
DevMode bool `env:"LOGGER_DEV_MODE" envDefault:"false"`
Encoder string `env:"LOGGER_ENCODER" envDefault:"console"`
}
// Logger methods interface
type Logger interface {
InitLogger()
Sync() error
Logger() *zap.Logger
SugarLogger() *zap.SugaredLogger
Debug(args ...interface{})
Debugf(template string, args ...interface{})
Info(args ...interface{})
Infof(template string, args ...interface{})
Warn(args ...interface{})
Warnf(template string, args ...interface{})
WarnMsg(msg string, err error)
Error(args ...interface{})
Errorf(template string, args ...interface{})
Err(msg string, err error)
DPanic(args ...interface{})
DPanicf(template string, args ...interface{})
Fatal(args ...interface{})
Fatalf(template string, args ...interface{})
Printf(template string, args ...interface{})
WithName(name string)
}
// Application logger
type AppLogger struct {
Level string
DevMode bool
Encoding string
sugarLogger *zap.SugaredLogger
logger *zap.Logger
}
// NewAppLogger App Logger constructor
func NewAppLogger(cfg *Config) *AppLogger {
return &AppLogger{Level: strings.ToLower(cfg.LogLevel), DevMode: cfg.DevMode, Encoding: cfg.Encoder}
}
// For mapping config logger to email_service logger levels
var loggerLevelMap = map[string]zapcore.Level{
"debug": zapcore.DebugLevel,
"info": zapcore.InfoLevel,
"warn": zapcore.WarnLevel,
"error": zapcore.ErrorLevel,
"dpanic": zapcore.DPanicLevel,
"panic": zapcore.PanicLevel,
"fatal": zapcore.FatalLevel,
}
func (l *AppLogger) getLoggerLevel() zapcore.Level {
level, exist := loggerLevelMap[l.Level]
if !exist {
return zapcore.DebugLevel
}
return level
}
// InitLogger Init logger
func (l *AppLogger) InitLogger() {
logLevel := l.getLoggerLevel()
logWriter := zapcore.AddSync(os.Stdout)
var encoderCfg zapcore.EncoderConfig
if l.DevMode {
encoderCfg = zap.NewDevelopmentEncoderConfig()
} else {
encoderCfg = zap.NewProductionEncoderConfig()
}
var encoder zapcore.Encoder
encoderCfg.EncodeTime = zapcore.ISO8601TimeEncoder
encoderCfg.EncodeDuration = zapcore.StringDurationEncoder
encoderCfg.EncodeLevel = zapcore.CapitalLevelEncoder
if l.Encoding == "console" {
if l.DevMode {
encoderCfg.EncodeLevel = zapcore.CapitalColorLevelEncoder
}
encoderCfg.ConsoleSeparator = " | "
encoder = zapcore.NewConsoleEncoder(encoderCfg)
} else {
encoderCfg.NameKey = "[SERVICE]"
encoderCfg.TimeKey = "[TIME]"
encoderCfg.LevelKey = "[LEVEL]"
encoderCfg.CallerKey = "[LINE]"
encoderCfg.MessageKey = "[MESSAGE]"
encoderCfg.FunctionKey = "[CALLER]"
encoderCfg.StacktraceKey = "[STACKTRACE]"
encoderCfg.EncodeName = zapcore.FullNameEncoder
encoder = zapcore.NewJSONEncoder(encoderCfg)
}
core := zapcore.NewCore(encoder, logWriter, zap.NewAtomicLevelAt(logLevel))
logger := zap.New(core, zap.AddCaller(), zap.AddCallerSkip(1))
l.logger = logger
l.sugarLogger = logger.Sugar()
zap.ReplaceGlobals(logger)
}
// Logger methods
// WithName add logger microservice name
func (l *AppLogger) WithName(name string) {
l.logger = l.logger.Named(name)
l.sugarLogger = l.logger.Sugar()
zap.ReplaceGlobals(l.logger)
}
// Debug uses fmt.Sprint to construct and log a message.
func (l *AppLogger) Debug(args ...interface{}) {
l.sugarLogger.Debug(args...)
}
// Debugf uses fmt.Sprintf to log a templated message
func (l *AppLogger) Debugf(template string, args ...interface{}) {
l.sugarLogger.Debugf(template, args...)
}
// Info uses fmt.Sprint to construct and log a message
func (l *AppLogger) Info(args ...interface{}) {
l.sugarLogger.Info(args...)
}
// Infof uses fmt.Sprintf to log a templated message.
func (l *AppLogger) Infof(template string, args ...interface{}) {
l.sugarLogger.Infof(template, args...)
}
// Printf uses fmt.Sprintf to log a templated message
func (l *AppLogger) Printf(template string, args ...interface{}) {
l.sugarLogger.Infof(template, args...)
}
// Warn uses fmt.Sprint to construct and log a message.
func (l *AppLogger) Warn(args ...interface{}) {
l.sugarLogger.Warn(args...)
}
// WarnMsg log error message with warn Level.
func (l *AppLogger) WarnMsg(msg string, err error) {
l.logger.Warn(msg, zap.String("error", err.Error()))
}
// Warnf uses fmt.Sprintf to log a templated message.
func (l *AppLogger) Warnf(template string, args ...interface{}) {
l.sugarLogger.Warnf(template, args...)
}
// Error uses fmt.Sprint to construct and log a message.
func (l *AppLogger) Error(args ...interface{}) {
l.sugarLogger.Error(args...)
}
// Errorf uses fmt.Sprintf to log a templated message.
func (l *AppLogger) Errorf(template string, args ...interface{}) {
l.sugarLogger.Errorf(template, args...)
}
// Err uses error to log a message.
func (l *AppLogger) Err(msg string, err error) {
l.logger.Error(msg, zap.Error(err))
}
// DPanic uses fmt.Sprint to construct and log a message. In development, the logger then panics. (See DPanicLevel for details.)
func (l *AppLogger) DPanic(args ...interface{}) {
l.sugarLogger.DPanic(args...)
}
// DPanicf uses fmt.Sprintf to log a templated message. In development, the logger then panics. (See DPanicLevel for details.)
func (l *AppLogger) DPanicf(template string, args ...interface{}) {
l.sugarLogger.DPanicf(template, args...)
}
// Panic uses fmt.Sprint to construct and log a message, then panics.
func (l *AppLogger) Panic(args ...interface{}) {
l.sugarLogger.Panic(args...)
}
// Panicf uses fmt.Sprintf to log a templated message, then panics
func (l *AppLogger) Panicf(template string, args ...interface{}) {
l.sugarLogger.Panicf(template, args...)
}
// Fatal uses fmt.Sprint to construct and log a message, then calls os.Exit.
func (l *AppLogger) Fatal(args ...interface{}) {
l.sugarLogger.Fatal(args...)
}
// Fatalf uses fmt.Sprintf to log a templated message, then calls os.Exit.
func (l *AppLogger) Fatalf(template string, args ...interface{}) {
l.sugarLogger.Fatalf(template, args...)
}
// Sync flushes any buffered log entries
func (l *AppLogger) Sync() error {
go l.logger.Sync() // nolint: errcheck
return l.sugarLogger.Sync()
}
func (l *AppLogger) SugarLogger() *zap.SugaredLogger {
return l.sugarLogger
}
func (l *AppLogger) Logger() *zap.Logger {
return l.logger
}