notebook notebook
首页
  • 计算机网络
  • 计算机系统
  • 数据结构与算法
  • 计算机专业课
  • 设计模式
  • 前端 (opens new window)
  • Java 开发
  • Python 开发
  • Golang 开发
  • Git
  • 软件设计与架构
  • 大数据与分布式系统
  • 常见开发工具

    • Nginx
  • 爬虫
  • Python 数据分析
  • 数据仓库
  • 中间件

    • MySQL
    • Redis
    • Elasticsearch
    • Kafka
  • 深度学习
  • 机器学习
  • 知识图谱
  • 图神经网络
  • 应用安全
  • 渗透测试
  • Linux
  • 云原生
面试
  • 收藏
  • paper 好句
GitHub (opens new window)

学习笔记

啦啦啦,向太阳~
首页
  • 计算机网络
  • 计算机系统
  • 数据结构与算法
  • 计算机专业课
  • 设计模式
  • 前端 (opens new window)
  • Java 开发
  • Python 开发
  • Golang 开发
  • Git
  • 软件设计与架构
  • 大数据与分布式系统
  • 常见开发工具

    • Nginx
  • 爬虫
  • Python 数据分析
  • 数据仓库
  • 中间件

    • MySQL
    • Redis
    • Elasticsearch
    • Kafka
  • 深度学习
  • 机器学习
  • 知识图谱
  • 图神经网络
  • 应用安全
  • 渗透测试
  • Linux
  • 云原生
面试
  • 收藏
  • paper 好句
GitHub (opens new window)
  • Java开发

  • Python开发

  • Golang开发

    • Posts

      • zap 日志库的使用
        • 1. 使用 Gin 构建一个 Web 应用
        • 2. Gin 框架使用 zap 日志库
          • 2.1 SugaredLogger 模式
          • 2.2 Logger 模式
        • 3. zap 日志库使用 lumberjack 库进行日志切割
        • 4. 总结
    • Go 语言核心 36 讲-赫林

  • Git

  • 软件设计与架构

  • 大数据与分布式系统

  • 区块链

  • Nginx

  • 开发
  • Golang开发
  • Posts
yubin
2023-02-13
目录

zap 日志库的使用

参考:Go 语言怎么使用 zap 日志库? (opens new window)

标准包的 log 包使用虽然方便,但支持的功能也简单。本文介绍 UBer 开源的日志库 zap。

# 1. 使用 Gin 构建一个 Web 应用

我们仅使用 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",
 })
}
1
2
3
4
5
6
7
8
9
10
11

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

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

# 2. Gin 框架使用 zap 日志库

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

# 2.1 SugaredLogger 模式

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

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

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

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

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

其中 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,
 }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18

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

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

func AddSync(w io.Writer) WriteSyncer
1

其中 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
}
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

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

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

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

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

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

# 2.2 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)
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21

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

# 3. 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)
}
1
2
3
4
5
6
7
8
9
10
11

lumberjack.Logger 的字段含义:

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

# 4. 总结

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

编辑 (opens new window)
上次更新: 2023/02/13, 06:24:22
Python 3.x 语法特性
Go语言基础知识

← Python 3.x 语法特性 Go语言基础知识→

最近更新
01
Deep Reinforcement Learning
10-03
02
误删数据后怎么办
04-06
03
MySQL 一主多从
03-22
更多文章>
Theme by Vdoing | Copyright © 2021-2024 yubincloud | MIT License
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式
×