Codebase list golang-github-go-kit-kit / 37e640d
json logger will now call fmt.Stringer if the type does not implement json.Marshaller or encoding.TextMarshaler Olivier Gagnon 8 years ago
2 changed file(s) with 72 addition(s) and 0 deletion(s). Raw diff Collapse all Expand all
00 package log
11
22 import (
3 "encoding"
34 "encoding/json"
45 "fmt"
56 "io"
4344 if x, ok := v.(error); ok {
4445 v = safeError(x)
4546 }
47
48 // We want json.Marshaler and encoding.TextMarshaller to take priority over
49 // err.Error() and v.String(). So we force a no-op if it's one of those 2
50 // case.
51 switch x := v.(type) {
52 case json.Marshaler:
53 case encoding.TextMarshaler:
54 case error:
55 v = safeError(x)
56 case fmt.Stringer:
57 v = safeString(x)
58 }
59
4660 dst[key] = v
4761 }
4862
7272 }
7373 }
7474
75 // aller implements json.Marshaler, encoding.TextMarshaler, and fmt.Stringer.
76 type aller struct{}
77
78 func (aller) MarshalJSON() ([]byte, error) {
79 return []byte("\"json\""), nil
80 }
81
82 func (aller) MarshalText() ([]byte, error) {
83 return []byte("text"), nil
84 }
85
86 func (aller) String() string {
87 return "string"
88 }
89
90 // textstringer implements encoding.TextMarshaler and fmt.Stringer.
91 type textstringer struct{}
92
93 func (textstringer) MarshalText() ([]byte, error) {
94 return []byte("text"), nil
95 }
96
97 func (textstringer) String() string {
98 return "string"
99 }
100
101 func TestJSONLoggerStringValue(t *testing.T) {
102 tests := []struct {
103 v interface{}
104 expected string
105 }{
106 {
107 v: aller{},
108 expected: `{"v":"json"}`,
109 },
110 {
111 v: textstringer{},
112 expected: `{"v":"text"}`,
113 },
114 {
115 v: stringer("string"),
116 expected: `{"v":"string"}`,
117 },
118 }
119
120 for _, test := range tests {
121 buf := &bytes.Buffer{}
122 logger := log.NewJSONLogger(buf)
123 if err := logger.Log("v", test.v); err != nil {
124 t.Fatal(err)
125 }
126
127 if want, have := test.expected+"\n", buf.String(); want != have {
128 t.Errorf("\nwant %#v\nhave %#v", want, have)
129 }
130 }
131 }
132
75133 type stringer string
76134
77135 func (s stringer) String() string {