序
本文次要钻研一下golang的zap的hook
实例
func hookDemo() { count := &atomic.Int64{} logger, _ := zap.NewProduction(zap.Hooks(func(entry zapcore.Entry) error { fmt.Println("count:", count.Inc(), "msg:", entry.Message) return nil })) defer logger.Sync() // flushes buffer, if any sugar := logger.Sugar() sugar.Infow("failed to fetch URL", // Structured context as loosely typed key-value pairs. "url", "https://golang.org", "attempt", 3, "backoff", time.Second, ) sugar.Info("hello world")}
输入
{"level":"info","ts":1608045721.769727,"caller":"zap/zap_demo.go:29","msg":"failed to fetch URL","url":"https://golang.org","attempt":3,"backoff":1}count: 1 msg: failed to fetch URL{"level":"info","ts":1608045721.769826,"caller":"zap/zap_demo.go:35","msg":"hello world"}count: 2 msg: hello world
Hooks
zap@v1.16.0/options.go
func Hooks(hooks ...func(zapcore.Entry) error) Option { return optionFunc(func(log *Logger) { log.core = zapcore.RegisterHooks(log.core, hooks...) })}
Hooks办法将log的core应用zapcore.RegisterHooks包装了一下
zapcore.RegisterHooks
zap@v1.16.0/zapcore/hook.go
func RegisterHooks(core Core, hooks ...func(Entry) error) Core { funcs := append([]func(Entry) error{}, hooks...) return &hooked{ Core: core, funcs: funcs, }}
RegisterHooks办法创立hooked,hooks赋值给hooked的funcs属性
hook
zap@v1.16.0/zapcore/hook.go
type hooked struct { Core funcs []func(Entry) error}func (h *hooked) Check(ent Entry, ce *CheckedEntry) *CheckedEntry { // Let the wrapped Core decide whether to log this message or not. This // also gives the downstream a chance to register itself directly with the // CheckedEntry. if downstream := h.Core.Check(ent, ce); downstream != nil { return downstream.AddCore(ent, h) } return ce}func (h *hooked) With(fields []Field) Core { return &hooked{ Core: h.Core.With(fields), funcs: h.funcs, }}func (h *hooked) Write(ent Entry, _ []Field) error { // Since our downstream had a chance to register itself directly with the // CheckedMessage, we don't need to call it here. var err error for i := range h.funcs { err = multierr.Append(err, h.funcs[i](ent)) } return err}
hooked内嵌了Core,它笼罩了Check、With、Write办法;Check办法将hooked增加到downstream;Write办法遍历hooks,执行回调
小结
Hooks办法将log的core应用zapcore.RegisterHooks包装了一下;RegisterHooks办法创立hooked,hooks赋值给hooked的funcs属性;hooked包装了core,因此须要在Check的时候把本人注册进去,而后在Write的时候就能够执行到本人注册的hooks。个别能够将metrics等简略的操作通过hook来实现,而简单的逻辑则最好通过实现zapcore.Core来做。
doc
- zap