序
本文次要钻研一下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