uber-zap 源码阅读

2018/10/15

zap是Uber开发的一个高性能、强类型、分level的go语言日志库。

阅读笔记:https://github.com/Chyroc/zap/pull/1/files

为了实现她的高性能,zap做了这些优化

buffer package

type Buffer struct {
	bs   []byte
	pool Pool
}

Buffer上定义各个类型数据的append

使用 sync.Pool 复用可能的对象,[]byte的初始大小为_size(1024),对一些小对象,能够避免alloc

func NewPool() Pool {
	return Pool{p: &sync.Pool{
		New: func() interface{} {
			return &Buffer{bs: make([]byte, 0, _size)}
		},
	}}
}

打印带有颜色文字

const (
	Black = iota + 30
	Red
	Green
	Yellow
	Blue
	Magenta
	Cyan
	White
)

fmt.Printf("\x1b[%dm%s\x1b[0m", c, s)

jsonEncoder

type jsonEncoder struct {
	*EncoderConfig
	buf *buffer.Buffer

	spaced bool
	openNamespaces int

	reflectBuf *buffer.Buffer
	reflectEnc *json.Encoder
}

这个结构是整个zap encode数据的核心, * buf就是上面介绍的自定义Buffer, * spaced控制是否打印可选的空格,如"a": true这里的空格是否有 * openNamespaces记录做大括号的数量,以便右边添加对应数量的右大括号 * reflectBufbuf类型一致,但是这里会配合reflectEnc使用json.Encoder解析interface数据(实际上,就是.Any的数据)

Field

type Field struct {
	Key       string
	Type      FieldType
	Integer   int64
	String    string
	Interface interface{} //存储数据
}

Field结构是每个数据的载体

Key的可选值

const (
	UnknownType         FieldType = iota // 未使用
	ArrayMarshalerType                   // 存于 Interface
	ObjectMarshalerType                  // 存于 Interface
	BinaryType                           // 存于 Interface
	BoolType                             // 存于 Integer
	ByteStringType                       // 存于 Interface
	Complex128Type                       // 存于 Interface
	Complex64Type                        // 存于 Interface
	DurationType                         // 存于 Integer
	Float64Type                          // 存于 Integer
	Float32Type                          // 存于 Integer
	Int64Type                            // 存于 Integer
	Int32Type                            // 存于 Integer
	Int16Type                            // 存于 Integer
	Int8Type                             // 存于 Integer
	StringType                           // 存于 String
	TimeType                             // 秒存于 Integer,Location存于interface
	Uint64Type                           // 存于 Integer
	Uint32Type                           // 存于 Integer
	Uint16Type                           // 存于 Integer
	Uint8Type                            // 存于 Integer
	UintptrType                          // 存于 Integer
	ReflectType                          // 存于 Interface
	NamespaceType                        // 没有 value
	StringerType                         // 存于 Interface
	ErrorType                            // 存于 Interface
	SkipType                             // 没有value
)

func (f Field) AddTo(enc ObjectEncoder)

在Field上定义的AddTo方法会将Field的数据encode到enc上