go第三方日志库uber-go/zap、lumberjack

(18) 2024-10-05 12:01:01

uber-go/zap、lumberjack

zap是uber开源的go语言高性能日志库,
lumberjack是zap官方推荐的日志分割库,
结合这两个库我们可以在项目中实现完整的日志机制,
例如:输出日志到文件、根据文件大小或日期分割等。

uber-go/zap

安装

在项目目录下命令行执行

go get -u go.uber.org/zap 

go第三方日志库uber-go/zap、lumberjack (https://mushiming.com/)  第1张

Logger

通过zap.NewDevelopment()或zap.NewProduction()都可以创建一个Logger,
它们的主要区别在于NewDevelopment会输出时间和包/文件/代码行信息,
而NewProduction不会,并且NewProduction不记录debug日志,
我们看一下例子:

zap.NewDevelopment()
package main import "go.uber.org/zap" func main() { 
    log, _ := zap.NewDevelopment() log.Debug("这是debug日志") log.Info("***************************") log.Info("这是info日志") log.Info("***************************") log.Warn("这是warn日志") log.Info("***************************") log.Error("这是error日志") log.Info("***************************") log.Panic("这是panic日志") } 

输出

GOROOT=D:\Program Files\Go #gosetup GOPATH=D:\work\goWorkspace;D:\work\goPath #gosetup "D:\Program Files\Go\bin\go.exe" build -o C:\Users\smart\AppData\Local\Temp\___go_build_main_go__1_.exe D:/work/goWorkspace/src/helloGoMod/log/main.go #gosetup C:\Users\smart\AppData\Local\Temp\___go_build_main_go__1_.exe #gosetup 2021-04-26T14:19:13.059+0800 DEBUG log/main.go:7 这是debug日志 2021-04-26T14:19:13.090+0800 INFO log/main.go:8 *************************** 2021-04-26T14:19:13.090+0800 INFO log/main.go:9 这是info日志 2021-04-26T14:19:13.090+0800 INFO log/main.go:10 *************************** 2021-04-26T14:19:13.090+0800 WARN log/main.go:11 这是warn日志 main.main D:/work/goWorkspace/src/helloGoMod/log/main.go:11 runtime.main D:/Program Files/Go/src/runtime/proc.go:225 2021-04-26T14:19:13.090+0800 INFO log/main.go:12 *************************** 2021-04-26T14:19:13.090+0800 ERROR log/main.go:13 这是error日志 main.main D:/work/goWorkspace/src/helloGoMod/log/main.go:13 runtime.main D:/Program Files/Go/src/runtime/proc.go:225 2021-04-26T14:19:13.090+0800 INFO log/main.go:14 *************************** 2021-04-26T14:19:13.090+0800 PANIC log/main.go:15 这是panic日志 main.main D:/work/goWorkspace/src/helloGoMod/log/main.go:15 runtime.main D:/Program Files/Go/src/runtime/proc.go:225 panic: 这是panic日志 goroutine 1 [running]: go.uber.org/zap/zapcore.(*CheckedEntry).Write(0xc00013c0c0, 0x0, 0x0, 0x0) D:/work/goWorkspace/pkg/mod/go.uber.org/zap@v1.16.0/zapcore/entry.go:234 +0x58d go.uber.org/zap.(*Logger).Panic(0xc0000482a0, 0x5b9d71, 0x11, 0x0, 0x0, 0x0) D:/work/goWorkspace/pkg/mod/go.uber.org/zap@v1.16.0/logger.go:226 +0x86 main.main() D:/work/goWorkspace/src/helloGoMod/log/main.go:15 +0x219 Process finished with exit code 2 
zap.NewProduction()
package main import "go.uber.org/zap" func main() { 
    log, _ := zap.NewProduction() log.Debug("这是debug日志") log.Info("***************************") log.Info("这是info日志") log.Info("***************************") log.Warn("这是warn日志") log.Info("***************************") log.Error("这是error日志") log.Info("***************************") log.Panic("这是panic日志") } 

输出

GOROOT=D:\Program Files\Go #gosetup GOPATH=D:\work\goWorkspace;D:\work\goPath #gosetup "D:\Program Files\Go\bin\go.exe" build -o C:\Users\smart\AppData\Local\Temp\___go_build_main_go__1_.exe D:/work/goWorkspace/src/helloGoMod/log/main.go #gosetup C:\Users\smart\AppData\Local\Temp\___go_build_main_go__1_.exe #gosetup { 
   "level":"info","ts":.,"caller":"log/main.go:8","msg":"***************************"} { 
   "level":"info","ts":.,"caller":"log/main.go:9","msg":"这是info日志"} { 
   "level":"info","ts":.,"caller":"log/main.go:10","msg":"***************************"} { 
   "level":"warn","ts":.,"caller":"log/main.go:11","msg":"这是warn日志"} { 
   "level":"info","ts":.,"caller":"log/main.go:12","msg":"***************************"} { 
   "level":"error","ts":.,"caller":"log/main.go:13","msg":"这是error日志","stacktrace":"main.main\n\tD:/work/goWorkspace/src/helloGoMod/log/main.go:13\nruntime.main\n\tD:/Program Files/Go/src/runtime/proc.go:225"} { 
   "level":"info","ts":.,"caller":"log/main.go:14","msg":"***************************"} { 
   "level":"panic","ts":.,"caller":"log/main.go:15","msg":"这是panic日志","stacktrace":"main.main\n\tD:/work/goWorkspace/src/helloGoMod/log/main.go:15\nruntime.main\n\tD:/Program Files/Go/src/runtime/proc.go:225"} panic: 这是panic日志 goroutine 1 [running]: go.uber.org/zap/zapcore.(*CheckedEntry).Write(0xc00013c0c0, 0x0, 0x0, 0x0) D:/work/goWorkspace/pkg/mod/go.uber.org/zap@v1.16.0/zapcore/entry.go:234 +0x58d go.uber.org/zap.(*Logger).Panic(0xc0000482a0, 0x5b9c50, 0x11, 0x0, 0x0, 0x0) D:/work/goWorkspace/pkg/mod/go.uber.org/zap@v1.16.0/logger.go:226 +0x86 main.main() D:/work/goWorkspace/src/helloGoMod/log/main.go:15 +0x219 Process finished with exit code 2 

SugaredLogger

如果我们需要像使用fmt.Printf一样输出,可以使用SugaredLogger,
通过log.Sugar()/Desugar()切换,
例子:

package main import ( "fmt" "go.uber.org/zap" ) func main() { 
    fmt.Printf("hello %v, helloZap\n", "yw") // hello yw, helloZap log, _ := zap.NewDevelopment() log.Info("hello " + "yw" + ", helloZap") // 2021-04-26T14:35:32.531+0800 INFO log/main.go:11 hello yw, helloZap // SugaredLogger sLog := log.Sugar() // 类似fmt.Println sLog.Info("hello ", "yw, ", "helloZap") // 2021-04-26T14:35:32.559+0800 INFO log/main.go:15 hello yw, helloZap // 类似fmt.Printf sLog.Infof("hello %v, helloZap", "yw") // 2021-04-26T14:35:32.559+0800 INFO log/main.go:17 hello yw, helloZap // 切换到标准Logger log = sLog.Desugar() } 

输出
go第三方日志库uber-go/zap、lumberjack (https://mushiming.com/)  第2张

日志输出到文件

创建Logger的方式和之前略有不同

package main import ( "go.uber.org/zap" "go.uber.org/zap/zapcore" "os" ) func main() { 
    // 编码器配置 config := zap.NewProductionEncoderConfig() // 指定时间编码器 config.EncodeTime = zapcore.ISO8601TimeEncoder // 日志级别用大写 config.EncodeLevel = zapcore.CapitalLevelEncoder // 编码器 encoder := zapcore.NewConsoleEncoder(config) // 日志文件 file, _ := os.Create("./test.log") // 写日志 sync := zapcore.AddSync(file) // 创建Logger core := zapcore.NewCore(encoder, sync, zapcore.DebugLevel) logger := zap.New(core, zap.AddCaller()) // 打印日志 logger.Info("hello " + "yw" + ", helloZap") // SugaredLogger sLog := logger.Sugar() // 类似fmt.Println sLog.Info("hello ", "yw, ", "helloZap") // 类似fmt.Printf sLog.Infof("hello %v, helloZap", "yw") } 

运行
go第三方日志库uber-go/zap、lumberjack (https://mushiming.com/)  第3张

lumberjack

因为zap不支持日志分割,这里引入lumberjack

安装

在项目目录下命令行执行

go get -u github.com/natefinch/lumberjack 

go第三方日志库uber-go/zap、lumberjack (https://mushiming.com/)  第4张

整合lumberjack

在WriteSyncer中添加lumberjack支持

package main import ( "github.com/natefinch/lumberjack" "go.uber.org/zap" "go.uber.org/zap/zapcore" ) func main() { 
    // 编码器配置 config := zap.NewProductionEncoderConfig() // 指定时间编码器 config.EncodeTime = zapcore.ISO8601TimeEncoder // 日志级别用大写 config.EncodeLevel = zapcore.CapitalLevelEncoder // 编码器 encoder := zapcore.NewConsoleEncoder(config) /*// 日志文件 file, _ := os.Create("./test.log") // 写日志 sync := zapcore.AddSync(file)*/ // 修改为添加lumberjack支持 lj := &lumberjack.Logger{ 
    Filename: "./test.log", MaxSize: 1, // 日志文件最大1M MaxBackups: 5, MaxAge: 7, // 日志保留最长时间7天 Compress: false, } sync := zapcore.AddSync(lj) // 创建Logger core := zapcore.NewCore(encoder, sync, zapcore.DebugLevel) logger := zap.New(core, zap.AddCaller()) // 打印日志 logger.Info("hello " + "yw" + ", helloZap") // SugaredLogger sLog := logger.Sugar() // 类似fmt.Println sLog.Info("hello ", "yw, ", "helloZap") // 类似fmt.Printf sLog.Infof("hello %v, helloZap", "yw") } 

我首先修改test.log文件内容超过1M,然后再运行代码
go第三方日志库uber-go/zap、lumberjack (https://mushiming.com/)  第5张
可以看到lumberjack已为我们生成了一个新的日志文件
go第三方日志库uber-go/zap、lumberjack (https://mushiming.com/)  第6张

THE END

发表回复