Ejemplo n.º 1
0
func (l logfmtLogger) Log(keyvals ...interface{}) error {
	// 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. We first collect all
	// of the bytes into b, and then call l.w.Write(b).
	b, err := logfmt.MarshalKeyvals(keyvals...)
	if err != nil {
		return err
	}
	b = append(b, '\n')
	if _, err := l.w.Write(b); err != nil {
		return err
	}
	return nil
}
Ejemplo n.º 2
0
func TestMarshalKeyvals(t *testing.T) {
	one := 1
	ptr := &one
	nilPtr := (*int)(nil)

	data := []struct {
		in   []interface{}
		want []byte
		err  error
	}{
		{in: nil, want: nil},
		{in: kv(), want: nil},
		{in: kv(nil, "v"), err: logfmt.ErrNilKey},
		{in: kv(nilPtr, "v"), err: logfmt.ErrNilKey},
		{in: kv("k"), want: []byte("k=null")},
		{in: kv("k", nil), want: []byte("k=null")},
		{in: kv("k", ""), want: []byte("k=")},
		{in: kv("k", "null"), want: []byte(`k="null"`)},
		{in: kv("k", "v"), want: []byte("k=v")},
		{in: kv("k", true), want: []byte("k=true")},
		{in: kv("k", 1), want: []byte("k=1")},
		{in: kv("k", ptr), want: []byte("k=1")},
		{in: kv("k", nilPtr), want: []byte("k=null")},
		{in: kv("k", 1.025), want: []byte("k=1.025")},
		{in: kv("k", 1e-3), want: []byte("k=0.001")},
		{in: kv("k", "v v"), want: []byte(`k="v v"`)},
		{in: kv("k", `"`), want: []byte(`k="\""`)},
		{in: kv("k", `=`), want: []byte(`k="="`)},
		{in: kv("k", `\`), want: []byte(`k=\`)},
		{in: kv("k", `=\`), want: []byte(`k="=\\"`)},
		{in: kv("k", `\"`), want: []byte(`k="\\\""`)},
		{in: kv("k1", "v1", "k2", "v2"), want: []byte("k1=v1 k2=v2")},
		{in: kv("k1", "v1", "k2", [2]int{}), want: []byte("k1=v1 k2=\"unsupported value type\"")},
		{in: kv([2]int{}, "v1", "k2", "v2"), want: []byte("k2=v2")},
		{in: kv("k", time.Date(2009, time.November, 10, 23, 0, 0, 0, time.UTC)), want: []byte("k=2009-11-10T23:00:00Z")},
		{in: kv("k", errorMarshaler{}), want: []byte("k=\"error marshaling value of type logfmt_test.errorMarshaler: marshal error\"")},
		{in: kv("k", decimalMarshaler{5, 9}), want: []byte("k=5.9")},
		{in: kv("k", (*decimalMarshaler)(nil)), want: []byte("k=null")},
		{in: kv("k", decimalStringer{5, 9}), want: []byte("k=5.9")},
		{in: kv("k", (*decimalStringer)(nil)), want: []byte("k=null")},
		{in: kv("k", marshalerStringer{5, 9}), want: []byte("k=5.9")},
		{in: kv("k", (*marshalerStringer)(nil)), want: []byte("k=null")},
		{in: kv(one, "v"), want: []byte("1=v")},
		{in: kv(ptr, "v"), want: []byte("1=v")},
		{in: kv((*marshalerStringer)(nil), "v"), err: logfmt.ErrNilKey},
		{in: kv(decimalMarshaler{5, 9}, "v"), want: []byte("5.9=v")},
		{in: kv((*decimalMarshaler)(nil), "v"), err: logfmt.ErrNilKey},
		{in: kv(decimalStringer{5, 9}, "v"), want: []byte("5.9=v")},
		{in: kv((*decimalStringer)(nil), "v"), err: logfmt.ErrNilKey},
		{in: kv(marshalerStringer{5, 9}, "v"), want: []byte("5.9=v")},
	}

	for _, d := range data {
		got, err := logfmt.MarshalKeyvals(d.in...)
		if err != d.err {
			t.Errorf("%#v: got error: %v, want error: %v", d.in, err, d.err)
		}
		if got, want := got, d.want; !reflect.DeepEqual(got, want) {
			t.Errorf("%#v: got '%s', want '%s'", d.in, got, want)
		}
	}
}