blob: d57e28aa57f36379d1efc21dadfbb5b633697eeb [file] [log] [blame]
Matteo Scandoloa4285862020-12-01 18:10:10 -08001package log
2
David K. Bainbridge06631892021-08-19 13:07:00 +00003import (
4 "fmt"
5 "reflect"
6)
Matteo Scandoloa4285862020-12-01 18:10:10 -08007
8// InterleavedKVToFields converts keyValues a la Span.LogKV() to a Field slice
9// a la Span.LogFields().
10func InterleavedKVToFields(keyValues ...interface{}) ([]Field, error) {
11 if len(keyValues)%2 != 0 {
12 return nil, fmt.Errorf("non-even keyValues len: %d", len(keyValues))
13 }
14 fields := make([]Field, len(keyValues)/2)
15 for i := 0; i*2 < len(keyValues); i++ {
16 key, ok := keyValues[i*2].(string)
17 if !ok {
18 return nil, fmt.Errorf(
19 "non-string key (pair #%d): %T",
20 i, keyValues[i*2])
21 }
22 switch typedVal := keyValues[i*2+1].(type) {
23 case bool:
24 fields[i] = Bool(key, typedVal)
25 case string:
26 fields[i] = String(key, typedVal)
27 case int:
28 fields[i] = Int(key, typedVal)
29 case int8:
30 fields[i] = Int32(key, int32(typedVal))
31 case int16:
32 fields[i] = Int32(key, int32(typedVal))
33 case int32:
34 fields[i] = Int32(key, typedVal)
35 case int64:
36 fields[i] = Int64(key, typedVal)
37 case uint:
38 fields[i] = Uint64(key, uint64(typedVal))
39 case uint64:
40 fields[i] = Uint64(key, typedVal)
41 case uint8:
42 fields[i] = Uint32(key, uint32(typedVal))
43 case uint16:
44 fields[i] = Uint32(key, uint32(typedVal))
45 case uint32:
46 fields[i] = Uint32(key, typedVal)
47 case float32:
48 fields[i] = Float32(key, typedVal)
49 case float64:
50 fields[i] = Float64(key, typedVal)
51 default:
David K. Bainbridge06631892021-08-19 13:07:00 +000052 if typedVal == nil || (reflect.ValueOf(typedVal).Kind() == reflect.Ptr && reflect.ValueOf(typedVal).IsNil()) {
53 fields[i] = String(key, "nil")
54 continue
55 }
Matteo Scandoloa4285862020-12-01 18:10:10 -080056 // When in doubt, coerce to a string
57 fields[i] = String(key, fmt.Sprint(typedVal))
58 }
59 }
60 return fields, nil
61}