63 lines
1.3 KiB
Go
63 lines
1.3 KiB
Go
|
package log
|
||
|
|
||
|
import (
|
||
|
"bytes"
|
||
|
"io"
|
||
|
"sync"
|
||
|
|
||
|
"github.com/go-logfmt/logfmt"
|
||
|
)
|
||
|
|
||
|
type logfmtEncoder struct {
|
||
|
*logfmt.Encoder
|
||
|
buf bytes.Buffer
|
||
|
}
|
||
|
|
||
|
func (l *logfmtEncoder) Reset() {
|
||
|
l.Encoder.Reset()
|
||
|
l.buf.Reset()
|
||
|
}
|
||
|
|
||
|
var logfmtEncoderPool = sync.Pool{
|
||
|
New: func() interface{} {
|
||
|
var enc logfmtEncoder
|
||
|
enc.Encoder = logfmt.NewEncoder(&enc.buf)
|
||
|
return &enc
|
||
|
},
|
||
|
}
|
||
|
|
||
|
type logfmtLogger struct {
|
||
|
w io.Writer
|
||
|
}
|
||
|
|
||
|
// NewLogfmtLogger returns a logger that encodes keyvals to the Writer in
|
||
|
// logfmt format. Each log event produces no more than one call to w.Write.
|
||
|
// The passed Writer must be safe for concurrent use by multiple goroutines if
|
||
|
// the returned Logger will be used concurrently.
|
||
|
func NewLogfmtLogger(w io.Writer) Logger {
|
||
|
return &logfmtLogger{w}
|
||
|
}
|
||
|
|
||
|
func (l logfmtLogger) Log(keyvals ...interface{}) error {
|
||
|
enc := logfmtEncoderPool.Get().(*logfmtEncoder)
|
||
|
enc.Reset()
|
||
|
defer logfmtEncoderPool.Put(enc)
|
||
|
|
||
|
if err := enc.EncodeKeyvals(keyvals...); err != nil {
|
||
|
return err
|
||
|
}
|
||
|
|
||
|
// Add newline to the end of the buffer
|
||
|
if err := enc.EndRecord(); err != nil {
|
||
|
return err
|
||
|
}
|
||
|
|
||
|
// The Logger interface requires implementations to be safe for concurrent
|
||
|
// use by multiple goroutines. For this implementation that means making
|
||
|
// only one call to l.w.Write() for each call to Log.
|
||
|
if _, err := l.w.Write(enc.buf.Bytes()); err != nil {
|
||
|
return err
|
||
|
}
|
||
|
return nil
|
||
|
}
|