categraf/pkg/jsonx/jsonflattener.go

78 lines
1.6 KiB
Go

package jsonx
import (
"fmt"
)
type JSONFlattener struct {
Fields map[string]interface{}
}
// FlattenJSON flattens nested maps/interfaces into a fields map (ignoring bools and string)
func (f *JSONFlattener) FlattenJSON(
fieldname string,
v interface{}) error {
if f.Fields == nil {
f.Fields = make(map[string]interface{})
}
return f.FullFlattenJSON(fieldname, v, false, false)
}
// FullFlattenJSON flattens nested maps/interfaces into a fields map (including bools and string)
func (f *JSONFlattener) FullFlattenJSON(
fieldname string,
v interface{},
convertString bool,
convertBool bool,
) error {
if f.Fields == nil {
f.Fields = make(map[string]interface{})
}
switch t := v.(type) {
case map[string]interface{}:
for k, v := range t {
fieldkey := k
if fieldname != "" {
fieldkey = fieldname + "_" + fieldkey
}
err := f.FullFlattenJSON(fieldkey, v, convertString, convertBool)
if err != nil {
return err
}
}
case []interface{}:
// for i, v := range t {
// fieldkey := strconv.Itoa(i)
// if fieldname != "" {
// fieldkey = fieldname + "_" + fieldkey
// }
// err := f.FullFlattenJSON(fieldkey, v, convertString, convertBool)
// if err != nil {
// return err
// }
// }
return nil
case float64:
f.Fields[fieldname] = t
case string:
if !convertString {
return nil
}
f.Fields[fieldname] = v.(string)
case bool:
if !convertBool {
return nil
}
f.Fields[fieldname] = v.(bool)
case nil:
return nil
default:
return fmt.Errorf("JSON Flattener: got unexpected type %T with value %v (%s)",
t, t, fieldname)
}
return nil
}