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
 | |
| }
 |