Go 语言怎么使用 Zap 日志库?

本文我们通过在 Gin 构建的应用中,使用 Zap 记录请求日志,介绍了 Zap 的使用方式,最后还通过 lumberjack 日志切割库进行切割日志。

本文我们通过在 Gin 构建的应用中,使用 Zap 记录请求日志,介绍了 Zap 的使用方式,最后还通过 lumberjack 日志切割库进行切割日志。

​1、介绍

我们在之前的文章中介绍过标准库log包的使用方式,它虽然使用方便,但是它支持的功能比较简单。

本文我们介绍 uber 开源的日志库zap​,首先使用 Gin 框架构建一个 Web 应用,然后通过在该 Web 应用中记录日志,来介绍zap的使用方式。

最后,我们再使用开源的日志切割库lumberjack,进行日志切割。

2、使用 Gin 构建一个 Web 应用

本文重点不是介绍 gin 框架的使用方式,所以我们仅使用 gin 框架构建一个简单的 Web 应用,代码如下:

func main() {
r := gin.Default()
r.GET("/ping", ping)
r.Run()
}

func ping(c *gin.Context) {
c.JSON(http.StatusOK, gin.H{
"message": "pong",
})
}

阅读上面这段代码,访问http://127.0.0.1:8080/ping​,返回结果是{"message":"pong"}。

然后,我们使用zap​记录ping函数的请求日志。

3、Gin 框架使用 zap 日志库

Zap 支持两种模式,分别是SugaredLogger​和Logger​,其中SugaredLogger​模式比Logger模式执行速度更快。

SugaredLogger 模式

使用 Zap 日志库,首先需要使用New​函数创建一个Logger,代码如下:

func New(core zapcore.Core, options ...Option) *Logger

使用New​函数,接收一个zapcore.Core​类型的参数和一个Option​类型的可选参数,返回一个*Logger。

其中zap.Core​类型的参数,可以使用NewCore​函数创建,接收三个参数,分别是zapcore.Encoder​类型,zapcore.WriteSyncer​类型和zapcore.LevelEnabler类型,分别用于指定日志格式、日志路径和日志级别。

func NewCore(enc Encoder, ws WriteSyncer, enab LevelEnabler) Core

其中zapcore.Encoder​类型的参数,可以使用NewProductionEncoderConfig函数创建,返回一个用于生产环境的固定日志编码配置。

// NewProductionEncoderConfig returns an opinionated EncoderConfig for
// production environments.
func NewProductionEncoderConfig() zapcore.EncoderConfig {
return zapcore.EncoderConfig{
TimeKey: "ts",
LevelKey: "level",
NameKey: "logger",
CallerKey: "caller",
FunctionKey: zapcore.OmitKey,
MessageKey: "msg",
StacktraceKey: "stacktrace",
LineEnding: zapcore.DefaultLineEnding,
EncodeLevel: zapcore.LowercaseLevelEncoder,
EncodeTime: zapcore.EpochTimeEncoder,
EncodeDuration: zapcore.SecondsDurationEncoder,
EncodeCaller: zapcore.ShortCallerEncoder,
}
}

我们可以修改任意配置选项的值。

其中zapcore.WriteSyncer​类型的参数,可以使用AddSync​函数创建,该函数接收一个io.Writer类型的参数。

func AddSync(w io.Writer) WriteSyncer

其中zapcore.LevelEnabler​类型的参数,可以使用zapcore​包定义的常量zapcore.DebugLevel​,该常量是zapcore.Level​类型,并且zapcore.Level​类型实现了zapcore.LevelEnabler接口。

完整代码:

var sugaredLogger *zap.SugaredLogger

func main() {
InitLogger()
defer sugaredLogger.Sync()
r := gin.Default()
r.GET("/ping", ping)
r.Run()
}

func ping(c *gin.Context) {
sugaredLogger.Debug("call func ping")
c.JSON(http.StatusOK, gin.H{
"message": "pong",
})
}

func InitLogger() {
core := zapcore.NewCore(enc(), ws(), enab())
logger := zap.New(core)
sugaredLogger = logger.Sugar()
}

func enc() zapcore.Encoder {
cfg := zap.NewProductionEncoderConfig()
cfg.TimeKey = "time"
cfg.EncodeTime = zapcore.TimeEncoderOfLayout("2006-01-02 15:04:05")
return zapcore.NewJSONEncoder(cfg)
}

func ws() zapcore.WriteSyncer {
logFileName := fmt.Sprintf("./%v.log", time.Now().Format("2006-01-02"))
logFile, err := os.Create(logFileName)
if err != nil {
log.Fatal(err)
}
return zapcore.AddSync(logFile)
}

func enab() zapcore.LevelEnabler {
return zapcore.DebugLevel
}

运行程序,执行curl http://127.0.0.1:8080/ping。

可以看到,生成的日志文件xxx.log​,文件中是json格式的日志内容,我们可以根据实际需求修改为其他格式。

开发中,可能我们希望日志可以同时输出到日志文件和终端中,可以使用函数NewMultiWriteSyncer,代码如下:

func wsV2() zapcore.WriteSyncer {
return zapcore.NewMultiWriteSyncer(ws(), zapcore.AddSync(os.Stdout))
}

除了使用zap.New()​创建Logger​之外,Zap 还提供了开箱即用的三种创建Logger​的方式,分别是函数NewProduction,NewDevelopment​和Example(),感兴趣的读者朋友们,可以试用一下。

Logger 模式

接下来,我们简单介绍一下Logger​模式,它主要用于性能和类型安全比较重要的场景中,但是,它没有SugaredLogger模式简单易用,我们可以根据实际场景选择使用哪种模式。

我们修改一下现有代码,新创建InitLoggerV2​函数,其中enc,ws​和enab​函数的代码与SugaredLogger模式保持一致。

var loggerV2 *zap.Logger

func main() {
InitLoggerV2()
defer loggerV2.Sync()
r := gin.Default()
r.GET("/ping", ping)
r.Run()
}

func ping(c *gin.Context) {
loggerV2.Debug("call func ping", zap.Int("code", 200))
c.JSON(http.StatusOK, gin.H{
"message": "pong",
})
}

func InitLoggerV2() {
core := zapcore.NewCore(enc(), ws(), enab())
loggerV2 = zap.New(core)
}

阅读上面这段代码,我们可以发现,在使用zap记录日志时,我们需要显示指定数据类型,一般用于性能和类型安全比较重要的场景中。

4、zap 日志库使用 lumberjack 库进行日志切割

Zap 日志库也不支持日志切割的功能,我们可以使用lumberjack​日志切割库进行日志切割,关于lumberjack库的使用方式,我们在之前的文章介绍过,此处不再重复介绍,直接上代码:

func wsV3() zapcore.WriteSyncer {
logFileName := fmt.Sprintf("./%v.log", time.Now().Format("2006-01-02"))
lumberjackLogger := &lumberjack.Logger{
Filename: logFileName,
MaxSize: 1,
MaxBackups: 3,
MaxAge: 28,
Compress: false,
}
return zapcore.AddSync(lumberjackLogger)
}

lumberjack.Logger的字段含义:

  • Filename 日志保存文件路径
  • MaxSize 日志文件大小,单位是MB
  • MaxBackups 保留的日志文件数量
  • MaxAge 日志文件的最长保留时间,单位是天
  • Compress 日志文件是否需要压缩

5、总结

本文我们通过在 Gin 构建的应用中,使用 Zap 记录请求日志,介绍了 Zap 的使用方式,最后还通过lumberjack日志切割库进行切割日志。

参考资料:

  1. https://github.com/uber-go/zap
  2. https://pkg.go.dev/go.uber.org/zap

©本文为清一色官方代发,观点仅代表作者本人,与清一色无关。清一色对文中陈述、观点判断保持中立,不对所包含内容的准确性、可靠性或完整性提供任何明示或暗示的保证。本文不作为投资理财建议,请读者仅作参考,并请自行承担全部责任。文中部分文字/图片/视频/音频等来源于网络,如侵犯到著作权人的权利,请与我们联系(微信/QQ:1074760229)。转载请注明出处:清一色财经

(0)
打赏 微信扫码打赏 微信扫码打赏 支付宝扫码打赏 支付宝扫码打赏
清一色的头像清一色管理团队
上一篇 2023年5月6日 21:41
下一篇 2023年5月6日 21:41

相关推荐

发表评论

登录后才能评论

联系我们

在线咨询:1643011589-QQbutton

手机:13798586780

QQ/微信:1074760229

QQ群:551893940

工作时间:工作日9:00-18:00,节假日休息

关注微信