github.com/jxskiss/gopkg@v0.17.3/zlog/logfmt_encoder_test.go (about) 1 package zlog 2 3 import ( 4 "math" 5 "testing" 6 "time" 7 8 "github.com/stretchr/testify/assert" 9 "go.uber.org/zap" 10 "go.uber.org/zap/buffer" 11 "go.uber.org/zap/zapcore" 12 ) 13 14 func TestEncoderObjectFields(t *testing.T) { 15 tests := []struct { 16 desc string 17 expected string 18 f func(zapcore.Encoder) 19 }{ 20 {"binary", `k="YWIxMg=="`, func(e zapcore.Encoder) { e.AddBinary("k", []byte("ab12")) }}, 21 {"bool", `k\\=true`, func(e zapcore.Encoder) { e.AddBool(`k\`, true) }}, // test key escaping once 22 {"bool", `k=true`, func(e zapcore.Encoder) { e.AddBool("k", true) }}, 23 {"bool", `k=false`, func(e zapcore.Encoder) { e.AddBool("k", false) }}, 24 {"byteString", `k=v\\`, func(e zapcore.Encoder) { e.AddByteString(`k`, []byte(`v\`)) }}, 25 {"byteString", `k=v`, func(e zapcore.Encoder) { e.AddByteString("k", []byte("v")) }}, 26 {"byteString", `k=`, func(e zapcore.Encoder) { e.AddByteString("k", []byte{}) }}, 27 {"byteString", `k=`, func(e zapcore.Encoder) { e.AddByteString("k", nil) }}, 28 {"byteString", `k="a b"`, func(e zapcore.Encoder) { e.AddByteString("k", []byte("a b")) }}, 29 {"complex128", `k=1+2i`, func(e zapcore.Encoder) { e.AddComplex128("k", 1+2i) }}, 30 {"complex64", `k=1+2i`, func(e zapcore.Encoder) { e.AddComplex64("k", 1+2i) }}, 31 {"duration", `k=0.000000001`, func(e zapcore.Encoder) { e.AddDuration("k", 1) }}, 32 {"float64", `k=1`, func(e zapcore.Encoder) { e.AddFloat64("k", 1.0) }}, 33 {"float64", `k=10000000000`, func(e zapcore.Encoder) { e.AddFloat64("k", 1e10) }}, 34 {"float64", `k=NaN`, func(e zapcore.Encoder) { e.AddFloat64("k", math.NaN()) }}, 35 {"float64", `k=+Inf`, func(e zapcore.Encoder) { e.AddFloat64("k", math.Inf(1)) }}, 36 {"float64", `k=-Inf`, func(e zapcore.Encoder) { e.AddFloat64("k", math.Inf(-1)) }}, 37 {"float32", `k=1`, func(e zapcore.Encoder) { e.AddFloat32("k", 1.0) }}, 38 {"float32", `k=10000000000`, func(e zapcore.Encoder) { e.AddFloat32("k", 1e10) }}, 39 {"float32", `k=NaN`, func(e zapcore.Encoder) { e.AddFloat32("k", float32(math.NaN())) }}, 40 {"float32", `k=+Inf`, func(e zapcore.Encoder) { e.AddFloat32("k", float32(math.Inf(1))) }}, 41 {"float32", `k=-Inf`, func(e zapcore.Encoder) { e.AddFloat32("k", float32(math.Inf(-1))) }}, 42 {"int", `k=42`, func(e zapcore.Encoder) { e.AddInt("k", 42) }}, 43 {"int64", `k=42`, func(e zapcore.Encoder) { e.AddInt64("k", 42) }}, 44 {"int32", `k=42`, func(e zapcore.Encoder) { e.AddInt32("k", 42) }}, 45 {"int16", `k=42`, func(e zapcore.Encoder) { e.AddInt16("k", 42) }}, 46 {"int8", `k=42`, func(e zapcore.Encoder) { e.AddInt8("k", 42) }}, 47 {"string", `k=v\\`, func(e zapcore.Encoder) { e.AddString(`k`, `v\`) }}, 48 {"string", `k=v`, func(e zapcore.Encoder) { e.AddString("k", "v") }}, 49 {"string", `k=`, func(e zapcore.Encoder) { e.AddString("k", "") }}, 50 {"string", `k="a b"`, func(e zapcore.Encoder) { e.AddString("k", "a b") }}, 51 {"time", `k=1`, func(e zapcore.Encoder) { e.AddTime("k", time.Unix(1, 0)) }}, 52 {"uint", `k=42`, func(e zapcore.Encoder) { e.AddUint("k", 42) }}, 53 {"uint64", `k=42`, func(e zapcore.Encoder) { e.AddUint64("k", 42) }}, 54 {"uint32", `k=42`, func(e zapcore.Encoder) { e.AddUint32("k", 42) }}, 55 {"uint16", `k=42`, func(e zapcore.Encoder) { e.AddUint16("k", 42) }}, 56 {"uint8", `k=42`, func(e zapcore.Encoder) { e.AddUint8("k", 42) }}, 57 {"uintptr", `k=42`, func(e zapcore.Encoder) { e.AddUintptr("k", 42) }}, 58 { 59 desc: "array (success)", 60 expected: `k=a,b`, 61 f: func(e zapcore.Encoder) { 62 assert.NoError( 63 t, 64 e.AddArray(`k`, zapcore.ArrayMarshalerFunc(func(enc zapcore.ArrayEncoder) error { 65 for _, s := range []string{"a", "b"} { 66 enc.AppendString(s) 67 } 68 return nil 69 }), 70 ), 71 "Unexpected error calling MarshalLogArray.", 72 ) 73 }, 74 }, 75 { 76 desc: "namespace", 77 expected: `outermost.outer.foo=1 outermost.outer.inner.foo=2`, 78 f: func(e zapcore.Encoder) { 79 e.OpenNamespace("outermost") 80 e.OpenNamespace("outer") 81 e.AddInt("foo", 1) 82 e.OpenNamespace("inner") 83 e.AddInt("foo", 2) 84 e.OpenNamespace("innermost") 85 }, 86 }, 87 } 88 89 for _, tt := range tests { 90 assertOutput(t, tt.desc, tt.expected, tt.f) 91 } 92 } 93 94 func assertOutput(t testing.TB, desc string, expected string, f func(zapcore.Encoder)) { 95 enc := &logfmtEncoder{buf: bufferpool.Get(), EncoderConfig: &zapcore.EncoderConfig{ 96 EncodeTime: zapcore.EpochTimeEncoder, 97 EncodeDuration: zapcore.SecondsDurationEncoder, 98 }} 99 f(enc) 100 assert.Equal(t, expected, enc.buf.String(), "Unexpected encoder output after adding a %s.", desc) 101 102 enc.truncate() 103 enc.AddString("foo", "bar") 104 f(enc) 105 expectedPrefix := `foo=bar` 106 if expected != "" { 107 // If we expect output, it should be comma-separated from the previous 108 // field. 109 expectedPrefix += " " 110 } 111 assert.Equal(t, expectedPrefix+expected, enc.buf.String(), "Unexpected encoder output after adding a %s as a second field.", desc) 112 } 113 114 func TestEncodeCaller(t *testing.T) { 115 enc := &logfmtEncoder{buf: bufferpool.Get(), EncoderConfig: &zapcore.EncoderConfig{ 116 EncodeTime: zapcore.EpochTimeEncoder, 117 EncodeDuration: zapcore.SecondsDurationEncoder, 118 EncodeCaller: zapcore.ShortCallerEncoder, 119 }} 120 121 var buf *buffer.Buffer 122 var err error 123 encodeEntry := func() { 124 buf, err = enc.EncodeEntry( 125 zapcore.Entry{ 126 Level: zapcore.DebugLevel, 127 Time: time.Time{}, 128 LoggerName: "test", 129 Message: "caller test", 130 Caller: zapcore.EntryCaller{ 131 Defined: true, 132 File: "h2g2.go", 133 Line: 42, 134 }, 135 }, 136 []zapcore.Field{ 137 zap.String("k", "v"), 138 }, 139 ) 140 } 141 142 encodeEntry() 143 assert.Nil(t, err) 144 assert.Equal(t, "k=v\n", buf.String()) 145 146 enc.truncate() 147 enc.EncoderConfig.CallerKey = "caller" 148 encodeEntry() 149 assert.Nil(t, err) 150 assert.Equal(t, "caller=h2g2.go:42 k=v\n", buf.String()) 151 } 152 153 func TestEncodeStacktrace(t *testing.T) { 154 enc := &logfmtEncoder{buf: bufferpool.Get(), EncoderConfig: &zapcore.EncoderConfig{ 155 EncodeTime: zapcore.EpochTimeEncoder, 156 EncodeDuration: zapcore.SecondsDurationEncoder, 157 }} 158 159 var buf *buffer.Buffer 160 var err error 161 encodeEntry := func() { 162 buf, err = enc.EncodeEntry( 163 zapcore.Entry{ 164 Level: zapcore.DebugLevel, 165 Time: time.Time{}, 166 LoggerName: "test", 167 Message: "stacktrace test", 168 Stack: `panic: an unexpected error occurred 169 170 goroutine 1 [running]: 171 main.main() 172 /go/src/github.com/jsternberg/myawesomeproject/h2g2.go:4 +0x39 173 `, 174 }, 175 []zapcore.Field{ 176 zap.String("k", "v"), 177 }, 178 ) 179 } 180 181 encodeEntry() 182 assert.Nil(t, err) 183 assert.Equal(t, "k=v\n", buf.String()) 184 185 enc.truncate() 186 enc.EncoderConfig.StacktraceKey = "stacktrace" 187 encodeEntry() 188 assert.Nil(t, err) 189 assert.Equal(t, `k=v stacktrace="panic: an unexpected error occurred\n\ngoroutine 1 [running]:\nmain.main()\n\t\t/go/src/github.com/jsternberg/myawesomeproject/h2g2.go:4 +0x39\n" 190 `, buf.String()) 191 }