zap 学习笔记

zap

zap 是 uber 提供的 一个高性能的组件库

结构

01

一条结构化的日志大致包含5个过程:

  • 分配日志 Entry: 创建整个结构体,此时虽然没有传参(fields)进来,但是 fields 参数其实创建了
  • 检查级别,添加core: 如果 logger 同时配置了 hook,则 hook 会在 core check 后把自己添加到 cores 中
  • 根据选项添加 caller info 和 stack 信息: 只有大于等于级别的日志才会创建checked entry
  • Encoder 对 checked entry 进行编码: 创建最终的 byte slice,将 fields 通过自己的编码方式(append)编码成目标串
  • Write 编码后的目标串,并对剩余的 core 执行操作, hook也会在这时被调用

核心部分:

  • logger: zap 的接口层,包含Log 对象、Level 对象、Field 对象、config 等基本对象
  • zapcore: zap 的核心逻辑,包含field 的管理、level 的判断、encode 编码日志、输出日志
  • encoder: json 或者其它编码方式的实现
  • utils: SubLog,Hook,SurgarLog/grpclogger/stdlogger

代码

demo

func main() {
	logger, _ := zap.NewProduction()
	// 生产配置信息
	defer logger.Sync()
	// flush 
	logger.Info("failed to fetch URL",
		// Structured context as strongly typed Field values.
		zap.String("url", "127.0.0.1"),
		zap.Int("attempt", 3),
		zap.Duration("backoff", time.Second),
	)
}

核心代码

func (log *Logger) Info(msg string, fields ...Field) {
	if ce := log.check(InfoLevel, msg); ce != nil {
		// 检查是否需要写入日志
		ce.Write(fields...)
	}
}
func (ce *CheckedEntry) Write(fields ...Field) {
	......

	// 写日志
	for i := range ce.cores {
		err = multierr.Append(err, ce.cores[i].Write(ce.Entry, fields))
	}

	// ce.cores[i].Write(ce.Entry, fields)
	// 先获取 encode 然后 write
	....
}	
posted @ 2021-01-08 17:26  S&L·chuck  阅读(305)  评论(0编辑  收藏  举报