Add support for hex-encoded of byte slice (#42)

This commit is contained in:
Max Wolter 2018-03-15 18:29:26 +01:00 committed by Olivier Poitrey
parent b62d797a8d
commit 1c575db928
10 changed files with 139 additions and 8 deletions

View File

@ -64,6 +64,12 @@ func (a *Array) Bytes(val []byte) *Array {
return a return a
} }
// Hex append the val as a hex string to the array.
func (a *Array) Hex(val []byte) *Array {
a.buf = json.AppendHex(append(a.buf, ','), val)
return a
}
// Err append the err as a string to the array. // Err append the err as a string to the array.
func (a *Array) Err(err error) *Array { func (a *Array) Err(err error) *Array {
a.buf = json.AppendError(append(a.buf, ','), err) a.buf = json.AppendError(append(a.buf, ','), err)

View File

@ -21,9 +21,11 @@ func TestArray(t *testing.T) {
Float32(11). Float32(11).
Float64(12). Float64(12).
Str("a"). Str("a").
Bytes([]byte("b")).
Hex([]byte{0x1f}).
Time(time.Time{}). Time(time.Time{}).
Dur(0) Dur(0)
want := `[true,1,2,3,4,5,6,7,8,9,10,11,12,"a","0001-01-01T00:00:00Z",0]` want := `[true,1,2,3,4,5,6,7,8,9,10,11,12,"a","b","1f","0001-01-01T00:00:00Z",0]`
if got := string(a.write([]byte{})); got != want { if got := string(a.write([]byte{})); got != want {
t.Errorf("Array.write()\ngot: %s\nwant: %s", got, want) t.Errorf("Array.write()\ngot: %s\nwant: %s", got, want)
} }

View File

@ -79,6 +79,12 @@ func (c Context) Bytes(key string, val []byte) Context {
return c return c
} }
// Hex adds the field key with val as a hex string to the logger context.
func (c Context) Hex(key string, val []byte) Context {
c.l.context = json.AppendHex(json.AppendKey(c.l.context, key), val)
return c
}
// RawJSON adds already encoded JSON to context. // RawJSON adds already encoded JSON to context.
// //
// No sanity check is performed on b; it must not contain carriage returns and // No sanity check is performed on b; it must not contain carriage returns and

View File

@ -219,6 +219,15 @@ func (e *Event) Bytes(key string, val []byte) *Event {
return e return e
} }
// Hex adds the field key with val as a hex string to the *Event context.
func (e *Event) Hex(key string, val []byte) *Event {
if e == nil {
return e
}
e.buf = json.AppendHex(json.AppendKey(e.buf, key), val)
return e
}
// RawJSON adds already encoded JSON to the log line under key. // RawJSON adds already encoded JSON to the log line under key.
// //
// No sanity check is performed on b; it must not contain carriage returns and // No sanity check is performed on b; it must not contain carriage returns and

View File

@ -1,5 +1,6 @@
package json package json
// AppendKey appends a new key to the output JSON.
func AppendKey(dst []byte, key string) []byte { func AppendKey(dst []byte, key string) []byte {
if len(dst) > 1 { if len(dst) > 1 {
dst = append(dst, ',') dst = append(dst, ',')
@ -8,6 +9,8 @@ func AppendKey(dst []byte, key string) []byte {
return append(dst, ':') return append(dst, ':')
} }
// AppendError encodes the error string to json and appends
// the encoded string to the input byte slice.
func AppendError(dst []byte, err error) []byte { func AppendError(dst []byte, err error) []byte {
if err == nil { if err == nil {
return append(dst, `null`...) return append(dst, `null`...)
@ -15,6 +18,8 @@ func AppendError(dst []byte, err error) []byte {
return AppendString(dst, err.Error()) return AppendString(dst, err.Error())
} }
// AppendErrors encodes the error strings to json and
// appends the encoded string list to the input byte slice.
func AppendErrors(dst []byte, errs []error) []byte { func AppendErrors(dst []byte, errs []error) []byte {
if len(errs) == 0 { if len(errs) == 0 {
return append(dst, '[', ']') return append(dst, '[', ']')

View File

@ -4,6 +4,8 @@ import "unicode/utf8"
const hex = "0123456789abcdef" const hex = "0123456789abcdef"
// AppendStrings encodes the input strings to json and
// appends the encoded string list to the input byte slice.
func AppendStrings(dst []byte, vals []string) []byte { func AppendStrings(dst []byte, vals []string) []byte {
if len(vals) == 0 { if len(vals) == 0 {
return append(dst, '[', ']') return append(dst, '[', ']')
@ -123,6 +125,19 @@ func AppendBytes(dst, s []byte) []byte {
return append(dst, '"') return append(dst, '"')
} }
// AppendHex encodes the input bytes to a hex string and appends
// the encoded string to the input byte slice.
//
// The operation loops though each byte and encodes it as hex using
// the hex lookup table.
func AppendHex(dst, s []byte) []byte {
dst = append(dst, '"')
for _, v := range s {
dst = append(dst, hex[v>>4], hex[v&0x0f])
}
return append(dst, '"')
}
// appendBytesComplex is a mirror of the appendStringComplex // appendBytesComplex is a mirror of the appendStringComplex
// with []byte arg // with []byte arg
func appendBytesComplex(dst, s []byte, i int) []byte { func appendBytesComplex(dst, s []byte, i int) []byte {

View File

@ -53,7 +53,18 @@ var encodeStringTests = []struct {
{"emoji \u2764\ufe0f!", `"emoji ❤️!"`}, {"emoji \u2764\ufe0f!", `"emoji ❤️!"`},
} }
func TestappendString(t *testing.T) { var encodeHexTests = []struct {
in byte
out string
}{
{0x00, `"00"`},
{0x0f, `"0f"`},
{0x10, `"10"`},
{0xf0, `"f0"`},
{0xff, `"ff"`},
}
func TestAppendString(t *testing.T) {
for _, tt := range encodeStringTests { for _, tt := range encodeStringTests {
b := AppendString([]byte{}, tt.in) b := AppendString([]byte{}, tt.in)
if got, want := string(b), tt.out; got != want { if got, want := string(b), tt.out; got != want {
@ -62,7 +73,7 @@ func TestappendString(t *testing.T) {
} }
} }
func TestappendBytes(t *testing.T) { func TestAppendBytes(t *testing.T) {
for _, tt := range encodeStringTests { for _, tt := range encodeStringTests {
b := AppendBytes([]byte{}, []byte(tt.in)) b := AppendBytes([]byte{}, []byte(tt.in))
if got, want := string(b), tt.out; got != want { if got, want := string(b), tt.out; got != want {
@ -71,6 +82,15 @@ func TestappendBytes(t *testing.T) {
} }
} }
func TestAppendHex(t *testing.T) {
for _, tt := range encodeHexTests {
b := AppendHex([]byte{}, []byte{tt.in})
if got, want := string(b), tt.out; got != want {
t.Errorf("appendHex(%x) = %s, want %s", tt.in, got, want)
}
}
}
func TestStringBytes(t *testing.T) { func TestStringBytes(t *testing.T) {
t.Parallel() t.Parallel()
// Test that encodeState.stringBytes and encodeState.string use the same encoding. // Test that encodeState.stringBytes and encodeState.string use the same encoding.
@ -108,7 +128,7 @@ func TestStringBytes(t *testing.T) {
} }
} }
func BenchmarkappendString(b *testing.B) { func BenchmarkAppendString(b *testing.B) {
tests := map[string]string{ tests := map[string]string{
"NoEncoding": `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa`, "NoEncoding": `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa`,
"EncodingFirst": `"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa`, "EncodingFirst": `"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa`,
@ -128,7 +148,7 @@ func BenchmarkappendString(b *testing.B) {
} }
} }
func BenchmarkappendBytes(b *testing.B) { func BenchmarkAppendBytes(b *testing.B) {
tests := map[string]string{ tests := map[string]string{
"NoEncoding": `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa`, "NoEncoding": `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa`,
"EncodingFirst": `"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa`, "EncodingFirst": `"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa`,

View File

@ -5,6 +5,8 @@ import (
"time" "time"
) )
// AppendTime formats the input time with the given format
// and appends the encoded string to the input byte slice.
func AppendTime(dst []byte, t time.Time, format string) []byte { func AppendTime(dst []byte, t time.Time, format string) []byte {
if format == "" { if format == "" {
return AppendInt64(dst, t.Unix()) return AppendInt64(dst, t.Unix())
@ -12,6 +14,8 @@ func AppendTime(dst []byte, t time.Time, format string) []byte {
return append(t.AppendFormat(append(dst, '"'), format), '"') return append(t.AppendFormat(append(dst, '"'), format), '"')
} }
// AppendTimes converts the input times with the given format
// and appends the encoded string list to the input byte slice.
func AppendTimes(dst []byte, vals []time.Time, format string) []byte { func AppendTimes(dst []byte, vals []time.Time, format string) []byte {
if format == "" { if format == "" {
return appendUnixTimes(dst, vals) return appendUnixTimes(dst, vals)
@ -45,6 +49,8 @@ func appendUnixTimes(dst []byte, vals []time.Time) []byte {
return dst return dst
} }
// AppendDuration formats the input duration with the given unit & format
// and appends the encoded string to the input byte slice.
func AppendDuration(dst []byte, d time.Duration, unit time.Duration, useInt bool) []byte { func AppendDuration(dst []byte, d time.Duration, unit time.Duration, useInt bool) []byte {
if useInt { if useInt {
return strconv.AppendInt(dst, int64(d/unit), 10) return strconv.AppendInt(dst, int64(d/unit), 10)
@ -52,6 +58,8 @@ func AppendDuration(dst []byte, d time.Duration, unit time.Duration, useInt bool
return AppendFloat64(dst, float64(d)/float64(unit)) return AppendFloat64(dst, float64(d)/float64(unit))
} }
// AppendDurations formats the input durations with the given unit & format
// and appends the encoded string list to the input byte slice.
func AppendDurations(dst []byte, vals []time.Duration, unit time.Duration, useInt bool) []byte { func AppendDurations(dst []byte, vals []time.Duration, unit time.Duration, useInt bool) []byte {
if len(vals) == 0 { if len(vals) == 0 {
return append(dst, '[', ']') return append(dst, '[', ']')

View File

@ -7,10 +7,14 @@ import (
"strconv" "strconv"
) )
// AppendBool converts the input bool to a string and
// appends the encoded string to the input byte slice.
func AppendBool(dst []byte, val bool) []byte { func AppendBool(dst []byte, val bool) []byte {
return strconv.AppendBool(dst, val) return strconv.AppendBool(dst, val)
} }
// AppendBools encodes the input bools to json and
// appends the encoded string list to the input byte slice.
func AppendBools(dst []byte, vals []bool) []byte { func AppendBools(dst []byte, vals []bool) []byte {
if len(vals) == 0 { if len(vals) == 0 {
return append(dst, '[', ']') return append(dst, '[', ']')
@ -26,10 +30,14 @@ func AppendBools(dst []byte, vals []bool) []byte {
return dst return dst
} }
// AppendInt converts the input int to a string and
// appends the encoded string to the input byte slice.
func AppendInt(dst []byte, val int) []byte { func AppendInt(dst []byte, val int) []byte {
return strconv.AppendInt(dst, int64(val), 10) return strconv.AppendInt(dst, int64(val), 10)
} }
// AppendInts encodes the input ints to json and
// appends the encoded string list to the input byte slice.
func AppendInts(dst []byte, vals []int) []byte { func AppendInts(dst []byte, vals []int) []byte {
if len(vals) == 0 { if len(vals) == 0 {
return append(dst, '[', ']') return append(dst, '[', ']')
@ -45,10 +53,14 @@ func AppendInts(dst []byte, vals []int) []byte {
return dst return dst
} }
// AppendInt8 converts the input []int8 to a string and
// appends the encoded string to the input byte slice.
func AppendInt8(dst []byte, val int8) []byte { func AppendInt8(dst []byte, val int8) []byte {
return strconv.AppendInt(dst, int64(val), 10) return strconv.AppendInt(dst, int64(val), 10)
} }
// AppendInts8 encodes the input int8s to json and
// appends the encoded string list to the input byte slice.
func AppendInts8(dst []byte, vals []int8) []byte { func AppendInts8(dst []byte, vals []int8) []byte {
if len(vals) == 0 { if len(vals) == 0 {
return append(dst, '[', ']') return append(dst, '[', ']')
@ -64,10 +76,14 @@ func AppendInts8(dst []byte, vals []int8) []byte {
return dst return dst
} }
// AppendInt16 converts the input int16 to a string and
// appends the encoded string to the input byte slice.
func AppendInt16(dst []byte, val int16) []byte { func AppendInt16(dst []byte, val int16) []byte {
return strconv.AppendInt(dst, int64(val), 10) return strconv.AppendInt(dst, int64(val), 10)
} }
// AppendInts16 encodes the input int16s to json and
// appends the encoded string list to the input byte slice.
func AppendInts16(dst []byte, vals []int16) []byte { func AppendInts16(dst []byte, vals []int16) []byte {
if len(vals) == 0 { if len(vals) == 0 {
return append(dst, '[', ']') return append(dst, '[', ']')
@ -83,10 +99,14 @@ func AppendInts16(dst []byte, vals []int16) []byte {
return dst return dst
} }
// AppendInt32 converts the input int32 to a string and
// appends the encoded string to the input byte slice.
func AppendInt32(dst []byte, val int32) []byte { func AppendInt32(dst []byte, val int32) []byte {
return strconv.AppendInt(dst, int64(val), 10) return strconv.AppendInt(dst, int64(val), 10)
} }
// AppendInts32 encodes the input int32s to json and
// appends the encoded string list to the input byte slice.
func AppendInts32(dst []byte, vals []int32) []byte { func AppendInts32(dst []byte, vals []int32) []byte {
if len(vals) == 0 { if len(vals) == 0 {
return append(dst, '[', ']') return append(dst, '[', ']')
@ -102,10 +122,14 @@ func AppendInts32(dst []byte, vals []int32) []byte {
return dst return dst
} }
// AppendInt64 converts the input int64 to a string and
// appends the encoded string to the input byte slice.
func AppendInt64(dst []byte, val int64) []byte { func AppendInt64(dst []byte, val int64) []byte {
return strconv.AppendInt(dst, val, 10) return strconv.AppendInt(dst, val, 10)
} }
// AppendInts64 encodes the input int64s to json and
// appends the encoded string list to the input byte slice.
func AppendInts64(dst []byte, vals []int64) []byte { func AppendInts64(dst []byte, vals []int64) []byte {
if len(vals) == 0 { if len(vals) == 0 {
return append(dst, '[', ']') return append(dst, '[', ']')
@ -121,10 +145,14 @@ func AppendInts64(dst []byte, vals []int64) []byte {
return dst return dst
} }
// AppendUint converts the input uint to a string and
// appends the encoded string to the input byte slice.
func AppendUint(dst []byte, val uint) []byte { func AppendUint(dst []byte, val uint) []byte {
return strconv.AppendUint(dst, uint64(val), 10) return strconv.AppendUint(dst, uint64(val), 10)
} }
// AppendUints encodes the input uints to json and
// appends the encoded string list to the input byte slice.
func AppendUints(dst []byte, vals []uint) []byte { func AppendUints(dst []byte, vals []uint) []byte {
if len(vals) == 0 { if len(vals) == 0 {
return append(dst, '[', ']') return append(dst, '[', ']')
@ -140,10 +168,14 @@ func AppendUints(dst []byte, vals []uint) []byte {
return dst return dst
} }
// AppendUint8 converts the input uint8 to a string and
// appends the encoded string to the input byte slice.
func AppendUint8(dst []byte, val uint8) []byte { func AppendUint8(dst []byte, val uint8) []byte {
return strconv.AppendUint(dst, uint64(val), 10) return strconv.AppendUint(dst, uint64(val), 10)
} }
// AppendUints8 encodes the input uint8s to json and
// appends the encoded string list to the input byte slice.
func AppendUints8(dst []byte, vals []uint8) []byte { func AppendUints8(dst []byte, vals []uint8) []byte {
if len(vals) == 0 { if len(vals) == 0 {
return append(dst, '[', ']') return append(dst, '[', ']')
@ -159,10 +191,14 @@ func AppendUints8(dst []byte, vals []uint8) []byte {
return dst return dst
} }
// AppendUint16 converts the input uint16 to a string and
// appends the encoded string to the input byte slice.
func AppendUint16(dst []byte, val uint16) []byte { func AppendUint16(dst []byte, val uint16) []byte {
return strconv.AppendUint(dst, uint64(val), 10) return strconv.AppendUint(dst, uint64(val), 10)
} }
// AppendUints16 encodes the input uint16s to json and
// appends the encoded string list to the input byte slice.
func AppendUints16(dst []byte, vals []uint16) []byte { func AppendUints16(dst []byte, vals []uint16) []byte {
if len(vals) == 0 { if len(vals) == 0 {
return append(dst, '[', ']') return append(dst, '[', ']')
@ -178,10 +214,14 @@ func AppendUints16(dst []byte, vals []uint16) []byte {
return dst return dst
} }
// AppendUint32 converts the input uint32 to a string and
// appends the encoded string to the input byte slice.
func AppendUint32(dst []byte, val uint32) []byte { func AppendUint32(dst []byte, val uint32) []byte {
return strconv.AppendUint(dst, uint64(val), 10) return strconv.AppendUint(dst, uint64(val), 10)
} }
// AppendUints32 encodes the input uint32s to json and
// appends the encoded string list to the input byte slice.
func AppendUints32(dst []byte, vals []uint32) []byte { func AppendUints32(dst []byte, vals []uint32) []byte {
if len(vals) == 0 { if len(vals) == 0 {
return append(dst, '[', ']') return append(dst, '[', ']')
@ -197,10 +237,14 @@ func AppendUints32(dst []byte, vals []uint32) []byte {
return dst return dst
} }
// AppendUint64 converts the input uint64 to a string and
// appends the encoded string to the input byte slice.
func AppendUint64(dst []byte, val uint64) []byte { func AppendUint64(dst []byte, val uint64) []byte {
return strconv.AppendUint(dst, uint64(val), 10) return strconv.AppendUint(dst, uint64(val), 10)
} }
// AppendUints64 encodes the input uint64s to json and
// appends the encoded string list to the input byte slice.
func AppendUints64(dst []byte, vals []uint64) []byte { func AppendUints64(dst []byte, vals []uint64) []byte {
if len(vals) == 0 { if len(vals) == 0 {
return append(dst, '[', ']') return append(dst, '[', ']')
@ -216,6 +260,8 @@ func AppendUints64(dst []byte, vals []uint64) []byte {
return dst return dst
} }
// AppendFloat converts the input float to a string and
// appends the encoded string to the input byte slice.
func AppendFloat(dst []byte, val float64, bitSize int) []byte { func AppendFloat(dst []byte, val float64, bitSize int) []byte {
// JSON does not permit NaN or Infinity. A typical JSON encoder would fail // JSON does not permit NaN or Infinity. A typical JSON encoder would fail
// with an error, but a logging library wants the data to get thru so we // with an error, but a logging library wants the data to get thru so we
@ -231,10 +277,14 @@ func AppendFloat(dst []byte, val float64, bitSize int) []byte {
return strconv.AppendFloat(dst, val, 'f', -1, bitSize) return strconv.AppendFloat(dst, val, 'f', -1, bitSize)
} }
// AppendFloat32 converts the input float32 to a string and
// appends the encoded string to the input byte slice.
func AppendFloat32(dst []byte, val float32) []byte { func AppendFloat32(dst []byte, val float32) []byte {
return AppendFloat(dst, float64(val), 32) return AppendFloat(dst, float64(val), 32)
} }
// AppendFloats32 encodes the input float32s to json and
// appends the encoded string list to the input byte slice.
func AppendFloats32(dst []byte, vals []float32) []byte { func AppendFloats32(dst []byte, vals []float32) []byte {
if len(vals) == 0 { if len(vals) == 0 {
return append(dst, '[', ']') return append(dst, '[', ']')
@ -250,10 +300,14 @@ func AppendFloats32(dst []byte, vals []float32) []byte {
return dst return dst
} }
// AppendFloat64 converts the input float64 to a string and
// appends the encoded string to the input byte slice.
func AppendFloat64(dst []byte, val float64) []byte { func AppendFloat64(dst []byte, val float64) []byte {
return AppendFloat(dst, val, 64) return AppendFloat(dst, val, 64)
} }
// AppendFloats64 encodes the input float64s to json and
// appends the encoded string list to the input byte slice.
func AppendFloats64(dst []byte, vals []float64) []byte { func AppendFloats64(dst []byte, vals []float64) []byte {
if len(vals) == 0 { if len(vals) == 0 {
return append(dst, '[', ']') return append(dst, '[', ']')
@ -269,6 +323,8 @@ func AppendFloats64(dst []byte, vals []float64) []byte {
return dst return dst
} }
// AppendInterface marshals the input interface to a string and
// appends the encoded string to the input byte slice.
func AppendInterface(dst []byte, i interface{}) []byte { func AppendInterface(dst []byte, i interface{}) []byte {
marshaled, err := json.Marshal(i) marshaled, err := json.Marshal(i)
if err != nil { if err != nil {

View File

@ -77,7 +77,9 @@ func TestInfo(t *testing.T) {
func TestWith(t *testing.T) { func TestWith(t *testing.T) {
out := &bytes.Buffer{} out := &bytes.Buffer{}
ctx := New(out).With(). ctx := New(out).With().
Str("foo", "bar"). Str("string", "foo").
Bytes("bytes", []byte("bar")).
Hex("hex", []byte{0x12, 0xef}).
RawJSON("json", []byte(`{"some":"json"}`)). RawJSON("json", []byte(`{"some":"json"}`)).
AnErr("some_err", nil). AnErr("some_err", nil).
Err(errors.New("some error")). Err(errors.New("some error")).
@ -99,7 +101,7 @@ func TestWith(t *testing.T) {
caller := fmt.Sprintf("%s:%d", file, line+3) caller := fmt.Sprintf("%s:%d", file, line+3)
log := ctx.Caller().Logger() log := ctx.Caller().Logger()
log.Log().Msg("") log.Log().Msg("")
if got, want := out.String(), `{"foo":"bar","json":{"some":"json"},"error":"some error","bool":true,"int":1,"int8":2,"int16":3,"int32":4,"int64":5,"uint":6,"uint8":7,"uint16":8,"uint32":9,"uint64":10,"float32":11,"float64":12,"time":"0001-01-01T00:00:00Z","caller":"`+caller+`"}`+"\n"; got != want { if got, want := out.String(), `{"string":"foo","bytes":"bar","hex":"12ef","json":{"some":"json"},"error":"some error","bool":true,"int":1,"int8":2,"int16":3,"int32":4,"int64":5,"uint":6,"uint8":7,"uint16":8,"uint32":9,"uint64":10,"float32":11,"float64":12,"time":"0001-01-01T00:00:00Z","caller":"`+caller+`"}`+"\n"; got != want {
t.Errorf("invalid log output:\ngot: %v\nwant: %v", got, want) t.Errorf("invalid log output:\ngot: %v\nwant: %v", got, want)
} }
} }
@ -143,6 +145,7 @@ func TestFields(t *testing.T) {
Caller(). Caller().
Str("string", "foo"). Str("string", "foo").
Bytes("bytes", []byte("bar")). Bytes("bytes", []byte("bar")).
Hex("hex", []byte{0x12, 0xef}).
RawJSON("json", []byte(`{"some":"json"}`)). RawJSON("json", []byte(`{"some":"json"}`)).
AnErr("some_err", nil). AnErr("some_err", nil).
Err(errors.New("some error")). Err(errors.New("some error")).
@ -163,7 +166,7 @@ func TestFields(t *testing.T) {
Time("time", time.Time{}). Time("time", time.Time{}).
TimeDiff("diff", now, now.Add(-10*time.Second)). TimeDiff("diff", now, now.Add(-10*time.Second)).
Msg("") Msg("")
if got, want := out.String(), `{"caller":"`+caller+`","string":"foo","bytes":"bar","json":{"some":"json"},"error":"some error","bool":true,"int":1,"int8":2,"int16":3,"int32":4,"int64":5,"uint":6,"uint8":7,"uint16":8,"uint32":9,"uint64":10,"float32":11,"float64":12,"dur":1000,"time":"0001-01-01T00:00:00Z","diff":10000}`+"\n"; got != want { if got, want := out.String(), `{"caller":"`+caller+`","string":"foo","bytes":"bar","hex":"12ef","json":{"some":"json"},"error":"some error","bool":true,"int":1,"int8":2,"int16":3,"int32":4,"int64":5,"uint":6,"uint8":7,"uint16":8,"uint32":9,"uint64":10,"float32":11,"float64":12,"dur":1000,"time":"0001-01-01T00:00:00Z","diff":10000}`+"\n"; got != want {
t.Errorf("invalid log output:\ngot: %v\nwant: %v", got, want) t.Errorf("invalid log output:\ngot: %v\nwant: %v", got, want)
} }
} }
@ -256,6 +259,7 @@ func TestFieldsDisabled(t *testing.T) {
log.Debug(). log.Debug().
Str("string", "foo"). Str("string", "foo").
Bytes("bytes", []byte("bar")). Bytes("bytes", []byte("bar")).
Hex("hex", []byte{0x12, 0xef}).
AnErr("some_err", nil). AnErr("some_err", nil).
Err(errors.New("some error")). Err(errors.New("some error")).
Bool("bool", true). Bool("bool", true).