版权声明 本站原创文章 由 萌叔 发表
转载请注明 萌叔 | http://vearne.cc

1. 前言

uber开源的高性能日志库zap, 除了性能远超logrus之外,还有很多诱人的功能,比如支持数据采样、支持通过HTTP服务动态调整日志级别。

前些天有同事问我,zap默认打印的日志格式,我不喜欢,可否自定义一下。 这个是日志库应该有的功能,zap怎么可能不支持。

下面我们来谈谈如何自定义日志格式,在zap中,它被称为Encoder, 在日志库中logrus,被做Formatter

2. 默认格式

目前 zap只支持2种日志格式

2.1 console

1.5392310605133479e+09	info	golab/test_zap.go:34	Info log	{"name": "buick2008", "age": 15}

2.2 json

{"level":"info","ts":1539234945.009923,"caller":"golab/test_zap.go:34","msg":"Info log","name":"buick2008","age":15}

3. 实现

  1. 为了实现自定义的Encoder 需要实现 zapcore.Encoder zapcore.PrimitiveArrayEncoder 所定义的接口

大部分接口实现可以照抄zapcore.jsonEncoder的代码实现 真正需要改动的是

EncodeEntry(ent zapcore.Entry, fields [] zapcore.Field) (*buffer.Buffer, error)
  1. 注册Encoder
    // 注册Encoder
    zap.RegisterEncoder("console2", MyEncoding)

用法示例

package main

import (
	"fmt"
	"go.uber.org/zap"
	"go.uber.org/zap/zapcore"
	"time"
	"github.com/vearne/golab/myencoder"
)


func MyEncoding(config zapcore.EncoderConfig) (zapcore.Encoder, error) {
	return myencoder.NewConsole2Encoder(config, true), nil
}


func main() {
	// 注册一个Encoder
	zap.RegisterEncoder("console2", MyEncoding)

	// 默认是Info级别
	logcfg := zap.NewProductionConfig()
	// 启用自定义的Encoding
	logcfg.Encoding = "console2"

	logger, err := logcfg.Build()
	if err != nil {
		fmt.Println("err", err)
	}

	defer logger.Sync()
	for i := 0; i < 3; i++ {
		time.Sleep(1 * time.Second)
		logger.Info("some message", zap.String("name", "buick2008"),
			zap.Int("age", 15))
	}
}

打印出的日志效果

"level": "info", "caller": "golab/test_zap.go:34", "msg": "some message"$$$ "name": "buick2008", "age": 15

这里用"$$$“分隔了msg 和 fields 这2部分

完整代码请见 vearne/golab 主要涉及的文件 test_zap.go console2_encoder.go

注意 由于时间原因,笔者并没有完整实现 zapcore.Encoder zapcore.PrimitiveArrayEncoder 所定义的接口,请勿直接在生产环境使用

推荐阅读


微信公众号