Example #1
0
func TestEncodeKeyval(t *testing.T) {
	data := []struct {
		key, value interface{}
		want       string
		err        error
	}{
		{key: "k", value: "v", want: "k=v"},
		{key: "k", value: nil, want: "k=null"},
		{key: `\`, value: "v", want: `\=v`},
		{key: "k", value: "", want: "k="},
		{key: "k", value: "null", want: `k="null"`},
		{key: "k", value: "<nil>", want: `k=<nil>`},
		{key: "k", value: true, want: "k=true"},
		{key: "k", value: 1, want: "k=1"},
		{key: "k", value: 1.025, want: "k=1.025"},
		{key: "k", value: 1e-3, want: "k=0.001"},
		{key: "k", value: 3.5 + 2i, want: "k=(3.5+2i)"},
		{key: "k", value: "v v", want: `k="v v"`},
		{key: "k", value: " ", want: `k=" "`},
		{key: "k", value: `"`, want: `k="\""`},
		{key: "k", value: `=`, want: `k="="`},
		{key: "k", value: `\`, want: `k=\`},
		{key: "k", value: `=\`, want: `k="=\\"`},
		{key: "k", value: `\"`, want: `k="\\\""`},
		{key: "k", value: [2]int{2, 19}, err: logfmt.ErrUnsupportedValueType},
		{key: "k", value: []string{"e1", "e 2"}, err: logfmt.ErrUnsupportedValueType},
		{key: "k", value: structData{"a a", 9}, err: logfmt.ErrUnsupportedValueType},
		{key: "k", value: decimalMarshaler{5, 9}, want: "k=5.9"},
		{key: "k", value: (*decimalMarshaler)(nil), want: "k=null"},
		{key: "k", value: decimalStringer{5, 9}, want: "k=5.9"},
		{key: "k", value: (*decimalStringer)(nil), want: "k=null"},
		{key: "k", value: marshalerStringer{5, 9}, want: "k=5.9"},
		{key: "k", value: (*marshalerStringer)(nil), want: "k=null"},
		{key: "k", value: new(nilMarshaler), want: "k=notnilmarshaler"},
		{key: "k", value: (*nilMarshaler)(nil), want: "k=nilmarshaler"},
		{key: (*marshalerStringer)(nil), value: "v", err: logfmt.ErrNilKey},
		{key: decimalMarshaler{5, 9}, value: "v", want: "5.9=v"},
		{key: (*decimalMarshaler)(nil), value: "v", err: logfmt.ErrNilKey},
		{key: decimalStringer{5, 9}, value: "v", want: "5.9=v"},
		{key: (*decimalStringer)(nil), value: "v", err: logfmt.ErrNilKey},
		{key: marshalerStringer{5, 9}, value: "v", want: "5.9=v"},
	}

	for _, d := range data {
		w := &bytes.Buffer{}
		enc := logfmt.NewEncoder(w)
		err := enc.EncodeKeyval(d.key, d.value)
		if err != d.err {
			t.Errorf("%#v, %#v: got error: %v, want error: %v", d.key, d.value, err, d.err)
		}
		if got, want := w.String(), d.want; got != want {
			t.Errorf("%#v, %#v: got '%s', want '%s'", d.key, d.value, got, want)
		}
	}
}
Example #2
0
func ExampleEncoder() {
	check := func(err error) {
		if err != nil {
			panic(err)
		}
	}

	e := logfmt.NewEncoder(os.Stdout)

	check(e.EncodeKeyval("id", 1))
	check(e.EncodeKeyval("dur", time.Second+time.Millisecond))
	check(e.EndRecord())

	check(e.EncodeKeyval("id", 1))
	check(e.EncodeKeyval("path", "/path/to/file"))
	check(e.EncodeKeyval("err", errors.New("file not found")))
	check(e.EndRecord())

	// Output:
	// id=1 dur=1.001s
	// id=1 path=/path/to/file err="file not found"
}
Example #3
0
)

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}
}
Example #4
0
func NewLogfmt(w io.Writer) *Logfmt {
	enc := logfmt.NewEncoder(w)
	return &Logfmt{
		enc: enc,
	}
}
Example #5
0
// New handler.
func New(w io.Writer) *Handler {
	return &Handler{
		enc: logfmt.NewEncoder(w),
	}
}