序
本文次要钻研一下 zerolog 的 send
实例
func sendDemo() {
zerolog.TimeFieldFormat = zerolog.TimeFormatUnix
log.Info().
Str("Name", "Tom").
Send()
log.Info().
Str("Name", "Tom").
Msg("hello world")
}
应用 Send 或者 Msg 来发送 log
输入
{"level":"info","Name":"Tom","time":1609509525}
{"level":"info","Name":"Tom","time":1609509525,"message":"hello world"}
Send
github.com/rs/zerolog@v1.20.0/event.go
// Send is equivalent to calling Msg("").
//
// NOTICE: once this method is called, the *Event should be disposed.
func (e *Event) Send() {
if e == nil {return}
e.msg("")
}
Send 办法相当于 Msg(“”)
msg
github.com/rs/zerolog@v1.20.0/event.go
func (e *Event) msg(msg string) {
for _, hook := range e.ch {hook.Run(e, e.level, msg)
}
if msg != "" {e.buf = enc.AppendString(enc.AppendKey(e.buf, MessageFieldName), msg)
}
if e.done != nil {defer e.done(msg)
}
if err := e.write(); err != nil {
if ErrorHandler != nil {ErrorHandler(err)
} else {fmt.Fprintf(os.Stderr, "zerolog: could not write event: %v\n", err)
}
}
}
msg 办法先执行 hook,之后对于有 msg 的增加 message 字段,如果 done 不为 nil 则 defer 注册回调,之后执行 e.write()
write
github.com/rs/zerolog@v1.20.0/event.go
func (e *Event) write() (err error) {
if e == nil {return nil}
if e.level != Disabled {e.buf = enc.AppendEndMarker(e.buf)
e.buf = enc.AppendLineBreak(e.buf)
if e.w != nil {_, err = e.w.WriteLevel(e.level, e.buf)
}
}
putEvent(e)
return
}
write 在 level 不为 Disabled 的时候会追加 endMarker 及 lineBreaker;对于 e.w 不为 nil 时,执行 e.w.WriteLevel(e.level, e.buf) 进行输入;之后执行 putEvent 偿还 event
putEvent
github.com/rs/zerolog@v1.20.0/event.go
func putEvent(e *Event) {
// Proper usage of a sync.Pool requires each entry to have approximately
// the same memory cost. To obtain this property when the stored type
// contains a variably-sized buffer, we add a hard limit on the maximum buffer
// to place back in the pool.
//
// See https://golang.org/issue/23199
const maxSize = 1 << 16 // 64KiB
if cap(e.buf) > maxSize {return}
eventPool.Put(e)
}
putEvent 办法先判断 e.buf 的大小是否超过 maxSize,超过则间接返回,否则执行 eventPool.Put(e) 将 event 偿还到 eventPool 中
Info
github.com/rs/zerolog@v1.20.0/log.go
// Info starts a new message with info level.
//
// You must call Msg on the returned event in order to send the event.
func (l *Logger) Info() *Event {return l.newEvent(InfoLevel, nil)
}
Info 办法执行的 l.newEvent(InfoLevel, nil)
newEvent
github.com/rs/zerolog@v1.20.0/log.go
func (l *Logger) newEvent(level Level, done func(string)) *Event {enabled := l.should(level)
if !enabled {return nil}
e := newEvent(l.w, level)
e.done = done
e.ch = l.hooks
if level != NoLevel {e.Str(LevelFieldName, LevelFieldMarshalFunc(level))
}
if l.context != nil && len(l.context) > 1 {e.buf = enc.AppendObjectData(e.buf, l.context)
}
return e
}
func newEvent(w LevelWriter, level Level) *Event {e := eventPool.Get().(*Event)
e.buf = e.buf[:0]
e.ch = nil
e.buf = enc.AppendBeginMarker(e.buf)
e.w = w
e.level = level
e.stack = false
return e
}
newEvent 办法从 eventPool 获取 Event,而后设置 done、hooks 等属性
小结
zerolog 的 Send 办法相当于 Msg(“”);newEvent 办法从 eventPool 获取 Event,而后设置 done、hooks 等属性;write 在 level 不为 Disabled 的时候会追加 endMarker 及 lineBreaker;对于 e.w 不为 nil 时,执行 e.w.WriteLevel(e.level, e.buf) 进行输入;之后执行 putEvent 偿还 event;
doc
- zerolog