github.com/go-kit/log@v0.2.1/logfmt_logger.go (about) 1 package log 2 3 import ( 4 "bytes" 5 "io" 6 "sync" 7 8 "github.com/go-logfmt/logfmt" 9 ) 10 11 type logfmtEncoder struct { 12 *logfmt.Encoder 13 buf bytes.Buffer 14 } 15 16 func (l *logfmtEncoder) Reset() { 17 l.Encoder.Reset() 18 l.buf.Reset() 19 } 20 21 var logfmtEncoderPool = sync.Pool{ 22 New: func() interface{} { 23 var enc logfmtEncoder 24 enc.Encoder = logfmt.NewEncoder(&enc.buf) 25 return &enc 26 }, 27 } 28 29 type logfmtLogger struct { 30 w io.Writer 31 } 32 33 // NewLogfmtLogger returns a logger that encodes keyvals to the Writer in 34 // logfmt format. Each log event produces no more than one call to w.Write. 35 // The passed Writer must be safe for concurrent use by multiple goroutines if 36 // the returned Logger will be used concurrently. 37 func NewLogfmtLogger(w io.Writer) Logger { 38 return &logfmtLogger{w} 39 } 40 41 func (l logfmtLogger) Log(keyvals ...interface{}) error { 42 enc := logfmtEncoderPool.Get().(*logfmtEncoder) 43 enc.Reset() 44 defer logfmtEncoderPool.Put(enc) 45 46 if err := enc.EncodeKeyvals(keyvals...); err != nil { 47 return err 48 } 49 50 // Add newline to the end of the buffer 51 if err := enc.EndRecord(); err != nil { 52 return err 53 } 54 55 // The Logger interface requires implementations to be safe for concurrent 56 // use by multiple goroutines. For this implementation that means making 57 // only one call to l.w.Write() for each call to Log. 58 if _, err := l.w.Write(enc.buf.Bytes()); err != nil { 59 return err 60 } 61 return nil 62 }