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
|
package logger
import (
"strings"
"go.uber.org/zap"
"go.uber.org/zap/zapcore"
)
// ChannelConfig configures loggers per channel.
type ChannelConfig struct {
// Dedicated channels per logger. By default logger allocated via named logger.
Channels map[string]Config `mapstructure:"channels"`
}
type Config struct {
// Mode configures logger based on some default template (development, production, off).
Mode string `mapstructure:"mode"`
// Level is the minimum enabled logging level. Note that this is a dynamic
// level, so calling ChannelConfig.Level.SetLevel will atomically change the log
// level of all loggers descended from this config.
Level string `mapstructure:"level"`
// Encoding sets the logger's encoding. InitDefault values are "json" and
// "console", as well as any third-party encodings registered via
// RegisterEncoder.
Encoding string `mapstructure:"encoding"`
// Output is a list of URLs or file paths to write logging output to.
// See Open for details.
Output []string `mapstructure:"output"`
// ErrorOutput is a list of URLs to write internal logger errors to.
// The default is standard error.
//
// Note that this setting only affects internal errors; for sample code that
// sends error-level logs to a different location from info- and debug-level
// logs, see the package-level AdvancedConfiguration example.
ErrorOutput []string `mapstructure:"errorOutput"`
}
// BuildLogger converts config into Zap configuration.
func (cfg *Config) BuildLogger() (*zap.Logger, error) {
var zCfg zap.Config
switch strings.ToLower(cfg.Mode) {
case "off", "none":
return zap.NewNop(), nil
case "production":
zCfg = zap.NewProductionConfig()
case "development":
zCfg = zap.Config{
Level: zap.NewAtomicLevelAt(zap.DebugLevel),
Development: true,
Encoding: "console",
EncoderConfig: zapcore.EncoderConfig{
// Keys can be anything except the empty string.
TimeKey: "T",
LevelKey: "L",
NameKey: "N",
CallerKey: "C",
FunctionKey: zapcore.OmitKey,
MessageKey: "M",
StacktraceKey: "S",
LineEnding: zapcore.DefaultLineEnding,
EncodeLevel: ColoredLevelEncoder,
EncodeTime: zapcore.ISO8601TimeEncoder,
EncodeDuration: zapcore.StringDurationEncoder,
EncodeCaller: zapcore.ShortCallerEncoder,
EncodeName: ColoredNameEncoder,
},
OutputPaths: []string{"stderr"},
ErrorOutputPaths: []string{"stderr"},
}
case "raw":
zCfg = zap.Config{
Level: zap.NewAtomicLevelAt(zap.InfoLevel),
Encoding: "console",
EncoderConfig: zapcore.EncoderConfig{
MessageKey: "message",
},
OutputPaths: []string{"stderr"},
ErrorOutputPaths: []string{"stderr"},
}
default:
zCfg = zap.Config{
Level: zap.NewAtomicLevelAt(zap.DebugLevel),
Encoding: "console",
EncoderConfig: zapcore.EncoderConfig{
MessageKey: "message",
LevelKey: "level",
TimeKey: "time",
NameKey: "name",
EncodeName: ColoredHashedNameEncoder,
EncodeLevel: ColoredLevelEncoder,
EncodeTime: UTCTimeEncoder,
EncodeCaller: zapcore.ShortCallerEncoder,
},
OutputPaths: []string{"stderr"},
ErrorOutputPaths: []string{"stderr"},
}
}
if cfg.Level != "" {
level := zap.NewAtomicLevel()
if err := level.UnmarshalText([]byte(cfg.Level)); err == nil {
zCfg.Level = level
}
}
if cfg.Encoding != "" {
zCfg.Encoding = cfg.Encoding
}
if len(cfg.Output) != 0 {
zCfg.OutputPaths = cfg.Output
}
if len(cfg.ErrorOutput) != 0 {
zCfg.ErrorOutputPaths = cfg.ErrorOutput
}
return zCfg.Build()
}
// InitDefault Initialize default logger
func (cfg *Config) InitDefault() {
if cfg.Mode == "" {
cfg.Mode = "development"
}
if cfg.Level == "" {
cfg.Level = "debug"
}
}
|