美文网首页
聊聊zerolog的send

聊聊zerolog的send

作者: go4it | 来源:发表于2021-01-01 22:33 被阅读0次

    本文主要研究一下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的send

          本文链接:https://www.haomeiwen.com/subject/uzrsoktx.html