本文次要钻研一下zerolog的LevelWriter

LevelWriter

github.com/rs/zerolog@v1.20.0/writer.go

// LevelWriter defines as interface a writer may implement in order// to receive level information with payload.type LevelWriter interface {    io.Writer    WriteLevel(level Level, p []byte) (n int, err error)}type Writer interface {    Write(p []byte) (n int, err error)}
LevelWriter接口内嵌了io.Writer接口,定义了WriteLevel办法

levelWriterAdapter

github.com/rs/zerolog@v1.20.0/writer.go

type levelWriterAdapter struct {    io.Writer}func (lw levelWriterAdapter) WriteLevel(l Level, p []byte) (n int, err error) {    return lw.Write(p)}
levelWriterAdapter内嵌了io.Writer属性,实现了LevelWriter的WriteLevel办法,该办法外部通过io.Writer属性的Write办法来输入

syncWriter

github.com/rs/zerolog@v1.20.0/writer.go

type syncWriter struct {    mu sync.Mutex    lw LevelWriter}func SyncWriter(w io.Writer) io.Writer {    if lw, ok := w.(LevelWriter); ok {        return &syncWriter{lw: lw}    }    return &syncWriter{lw: levelWriterAdapter{w}}}// Write implements the io.Writer interface.func (s *syncWriter) Write(p []byte) (n int, err error) {    s.mu.Lock()    defer s.mu.Unlock()    return s.lw.Write(p)}// WriteLevel implements the LevelWriter interface.func (s *syncWriter) WriteLevel(l Level, p []byte) (n int, err error) {    s.mu.Lock()    defer s.mu.Unlock()    return s.lw.WriteLevel(l, p)}
syncWriter实现了LevelWriter接口,其对Write及WriteLevel办法都进行了加锁;SyncWriter办法通过levelWriterAdapter来适配io.Writer

multiLevelWriter

github.com/rs/zerolog@v1.20.0/writer.go

type multiLevelWriter struct {    writers []LevelWriter}func (t multiLevelWriter) Write(p []byte) (n int, err error) {    for _, w := range t.writers {        n, err = w.Write(p)        if err != nil {            return        }        if n != len(p) {            err = io.ErrShortWrite            return        }    }    return len(p), nil}func (t multiLevelWriter) WriteLevel(l Level, p []byte) (n int, err error) {    for _, w := range t.writers {        n, err = w.WriteLevel(l, p)        if err != nil {            return        }        if n != len(p) {            err = io.ErrShortWrite            return        }    }    return len(p), nil}// MultiLevelWriter creates a writer that duplicates its writes to all the// provided writers, similar to the Unix tee(1) command. If some writers// implement LevelWriter, their WriteLevel method will be used instead of Write.func MultiLevelWriter(writers ...io.Writer) LevelWriter {    lwriters := make([]LevelWriter, 0, len(writers))    for _, w := range writers {        if lw, ok := w.(LevelWriter); ok {            lwriters = append(lwriters, lw)        } else {            lwriters = append(lwriters, levelWriterAdapter{w})        }    }    return multiLevelWriter{lwriters}}
multiLevelWriter定义了writers属性,它也实现了LevelWriter接口,其Write及WriteLevel办法均是遍历writers挨个执行对应操作;MultiLevelWriter办法通过levelWriterAdapter来适配io.Writer

实例

func multiLevelWriterDemo() {    consoleWriter := zerolog.ConsoleWriter{Out: os.Stdout}    multi := zerolog.MultiLevelWriter(consoleWriter, os.Stdout)    logger := zerolog.New(multi).With().Timestamp().Logger()    logger.Info().Msg("Hello World!")}
这里应用zerolog.MultiLevelWriter来指定多个输入

输入

8:02PM INF Hello World!{"level":"info","time":"2021-01-02T20:02:27+08:00","message":"Hello World!"}

小结

LevelWriter接口内嵌了io.Writer接口,定义了WriteLevel办法;levelWriterAdapter内嵌了io.Writer属性,实现了LevelWriter的WriteLevel办法,该办法外部通过io.Writer属性的Write办法来输入;SyncWriter办法通过levelWriterAdapter来适配io.Writer;MultiLevelWriter办法通过levelWriterAdapter来适配io.Writer。

doc

  • zerolog