func kvListFormat()

in klog.go [821:873]


func kvListFormat(b *bytes.Buffer, keysAndValues ...interface{}) {
	for i := 0; i < len(keysAndValues); i += 2 {
		var v interface{}
		k := keysAndValues[i]
		if i+1 < len(keysAndValues) {
			v = keysAndValues[i+1]
		} else {
			v = missingValue
		}
		b.WriteByte(' ')
		// Keys are assumed to be well-formed according to
		// https://github.com/kubernetes/community/blob/master/contributors/devel/sig-instrumentation/migration-to-structured-logging.md#name-arguments
		// for the sake of performance. Keys with spaces,
		// special characters, etc. will break parsing.
		if k, ok := k.(string); ok {
			// Avoid one allocation when the key is a string, which
			// normally it should be.
			b.WriteString(k)
		} else {
			b.WriteString(fmt.Sprintf("%s", k))
		}

		// The type checks are sorted so that more frequently used ones
		// come first because that is then faster in the common
		// cases. In Kubernetes, ObjectRef (a Stringer) is more common
		// than plain strings
		// (https://github.com/kubernetes/kubernetes/pull/106594#issuecomment-975526235).
		switch v := v.(type) {
		case fmt.Stringer:
			writeStringValue(b, true, stringerToString(v))
		case string:
			writeStringValue(b, true, v)
		case error:
			writeStringValue(b, true, v.Error())
		case []byte:
			// In https://github.com/kubernetes/klog/pull/237 it was decided
			// to format byte slices with "%+q". The advantages of that are:
			// - readable output if the bytes happen to be printable
			// - non-printable bytes get represented as unicode escape
			//   sequences (\uxxxx)
			//
			// The downsides are that we cannot use the faster
			// strconv.Quote here and that multi-line output is not
			// supported. If developers know that a byte array is
			// printable and they want multi-line output, they can
			// convert the value to string before logging it.
			b.WriteByte('=')
			b.WriteString(fmt.Sprintf("%+q", v))
		default:
			writeStringValue(b, false, fmt.Sprintf("%+v", v))
		}
	}
}