GoLang zap 日志框架

zap

安装

1
go get -u go.uber.org/zap

配置

  • SugaredLogger: 慢,支持结构化和printf风格的日志记录。
  • Logger: 快,内存分配次数也更少,只支持强类型的结构化日志记录。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
func main() {
// Example适合用在测试代码中,Development在开发环境中使用,Production用在生成环境。
logger := zap.NewExample()
defer logger.Sync()

url := "http://example.org/api"
logger.Info("failed to fetch URL",
zap.String("url", url),
zap.Int("attempt", 3),
zap.Duration("backoff", time.Second),
)

sugar := logger.Sugar()
sugar.Infow("failed to fetch URL",
"url", url,
"attempt", 3,
"backoff", time.Second,
)
sugar.Infof("Failed to fetch URL: %s", url)
}

使用Json配置初始化

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
func main{
// 使用Config 获取Logger
rawJSON := []byte(`{
"level":"debug",
"encoding":"json",
"outputPaths": ["stdout", "server.log"],
"errorOutputPaths": ["stderr"],
"initialFields":{"name":"dj"},
"encoderConfig": {
"messageKey": "message",
"levelKey": "level",
"levelEncoder": "lowercase"
}
}`)

var cfg zap.Config
if err := json.Unmarshal(rawJSON, &cfg); err != nil {
panic(err)
}
logger, err := cfg.Build(zap.AddCaller())
if err != nil {
panic(err)
}
defer logger.Sync()

logger.Info("server start work successfully!")
}

自定义日志输出

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
func main() {
// 定义日志的输出
file, _ := os.Create("./test.log")
// 多输出
writeSyncer := zapcore.NewMultiWriteSyncer(file, os.Stdout)
encoderConfig := zap.NewProductionEncoderConfig()
encoderConfig.EncodeTime = zapcore.ISO8601TimeEncoder
encoderConfig.EncodeLevel = zapcore.CapitalLevelEncoder
encoder := zapcore.NewJSONEncoder(zap.NewProductionEncoderConfig())
core := zapcore.NewCore(encoder, writeSyncer, zapcore.DebugLevel)

logger := zap.New(core)
sugarLogger := logger.Sugar()
sugarLogger.Info("test")
}

日志切割

1
go get -u github.com/natefinch/lumberjack 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
func main() {
// 日志切割
lumberJackLogger := &lumberjack.Logger{
Filename: "./test.log", // 日志文件的位置
MaxSize: 10, // 文件的最大大小 MB
MaxBackups: 5, // 保留旧文件个数
MaxAge: 30, // 保留旧文件最大天数
Compress: false, // 是否压缩/归档旧文件
}
writeSyncer := zapcore.AddSync(lumberJackLogger)
encoder := zapcore.NewJSONEncoder(zap.NewProductionEncoderConfig())
core := zapcore.NewCore(encoder, writeSyncer, zapcore.DebugLevel)
logger := zap.New(core)
sugarLogger := logger.Sugar()
sugarLogger.Info("test lumberJackLogger")
}

输出调用栈

1
2
3
4
5
6
7
8
9
func main() {
// 输出调用堆栈
logger, _ := zap.NewProduction(zap.AddStacktrace(zapcore.WarnLevel))
defer logger.Sync()

zap.ReplaceGlobals(logger)

zap.L().Warn("test warn")
}

与标准日志库搭配使用

1
2
3
4
5
6
7
8
9
10
11
func main() {
// 与标准日志库搭配使用
logger := zap.NewExample()
defer logger.Sync()

undo := zap.RedirectStdLog(logger)
log.Print("redirected standard library12")
undo()

log.Print("restored standard library")
}