@@ -95,9 +95,15 @@ func MergeKVs(first, second []interface{}) []interface{} {
9595 return merged
9696}
9797
98+ type Formatter struct {
99+ AnyToStringHook AnyToStringFunc
100+ }
101+
102+ type AnyToStringFunc func (v interface {}) string
103+
98104// MergeKVsInto is a variant of MergeKVs which directly formats the key/value
99105// pairs into a buffer.
100- func MergeAndFormatKVs (b * bytes.Buffer , first , second []interface {}) {
106+ func ( f Formatter ) MergeAndFormatKVs (b * bytes.Buffer , first , second []interface {}) {
101107 if len (first ) == 0 && len (second ) == 0 {
102108 // Nothing to do at all.
103109 return
@@ -107,7 +113,7 @@ func MergeAndFormatKVs(b *bytes.Buffer, first, second []interface{}) {
107113 // Nothing to be overridden, second slice is well-formed
108114 // and can be used directly.
109115 for i := 0 ; i < len (second ); i += 2 {
110- KVFormat (b , second [i ], second [i + 1 ])
116+ f . KVFormat (b , second [i ], second [i + 1 ])
111117 }
112118 return
113119 }
@@ -127,24 +133,28 @@ func MergeAndFormatKVs(b *bytes.Buffer, first, second []interface{}) {
127133 if overrides [key ] {
128134 continue
129135 }
130- KVFormat (b , key , first [i + 1 ])
136+ f . KVFormat (b , key , first [i + 1 ])
131137 }
132138 // Round down.
133139 l := len (second )
134140 l = l / 2 * 2
135141 for i := 1 ; i < l ; i += 2 {
136- KVFormat (b , second [i - 1 ], second [i ])
142+ f . KVFormat (b , second [i - 1 ], second [i ])
137143 }
138144 if len (second )% 2 == 1 {
139- KVFormat (b , second [len (second )- 1 ], missingValue )
145+ f . KVFormat (b , second [len (second )- 1 ], missingValue )
140146 }
141147}
142148
149+ func MergeAndFormatKVs (b * bytes.Buffer , first , second []interface {}) {
150+ Formatter {}.MergeAndFormatKVs (b , first , second )
151+ }
152+
143153const missingValue = "(MISSING)"
144154
145155// KVListFormat serializes all key/value pairs into the provided buffer.
146156// A space gets inserted before the first pair and between each pair.
147- func KVListFormat (b * bytes.Buffer , keysAndValues ... interface {}) {
157+ func ( f Formatter ) KVListFormat (b * bytes.Buffer , keysAndValues ... interface {}) {
148158 for i := 0 ; i < len (keysAndValues ); i += 2 {
149159 var v interface {}
150160 k := keysAndValues [i ]
@@ -153,13 +163,17 @@ func KVListFormat(b *bytes.Buffer, keysAndValues ...interface{}) {
153163 } else {
154164 v = missingValue
155165 }
156- KVFormat (b , k , v )
166+ f . KVFormat (b , k , v )
157167 }
158168}
159169
170+ func KVListFormat (b * bytes.Buffer , keysAndValues ... interface {}) {
171+ Formatter {}.KVListFormat (b , keysAndValues ... )
172+ }
173+
160174// KVFormat serializes one key/value pair into the provided buffer.
161175// A space gets inserted before the pair.
162- func KVFormat (b * bytes.Buffer , k , v interface {}) {
176+ func ( f Formatter ) KVFormat (b * bytes.Buffer , k , v interface {}) {
163177 b .WriteByte (' ' )
164178 // Keys are assumed to be well-formed according to
165179 // https://github.com/kubernetes/community/blob/master/contributors/devel/sig-instrumentation/migration-to-structured-logging.md#name-arguments
@@ -203,7 +217,7 @@ func KVFormat(b *bytes.Buffer, k, v interface{}) {
203217 case string :
204218 writeStringValue (b , true , value )
205219 default :
206- writeStringValue (b , false , fmt . Sprintf ( "%+v" , value ))
220+ writeStringValue (b , false , f . AnyToString ( value ))
207221 }
208222 case []byte :
209223 // In https://github.com/kubernetes/klog/pull/237 it was decided
@@ -220,8 +234,20 @@ func KVFormat(b *bytes.Buffer, k, v interface{}) {
220234 b .WriteByte ('=' )
221235 b .WriteString (fmt .Sprintf ("%+q" , v ))
222236 default :
223- writeStringValue (b , false , fmt .Sprintf ("%+v" , v ))
237+ writeStringValue (b , false , f .AnyToString (v ))
238+ }
239+ }
240+
241+ func KVFormat (b * bytes.Buffer , k , v interface {}) {
242+ Formatter {}.KVFormat (b , k , v )
243+ }
244+
245+ // AnyToString is the historic fallback formatter.
246+ func (f Formatter ) AnyToString (v interface {}) string {
247+ if f .AnyToStringHook != nil {
248+ return f .AnyToStringHook (v )
224249 }
250+ return fmt .Sprintf ("%+v" , v )
225251}
226252
227253// StringerToString converts a Stringer to a string,
0 commit comments