internal: FlattenJSON, flatten arrays as well

With HTTP JSON or Elasticsearch, one can also process values nested in arrays.
This commit is contained in:
Philip Silva 2016-01-12 12:12:49 +01:00 committed by Cameron Sparr
parent fb837ca66d
commit 3c89847489
4 changed files with 34 additions and 12 deletions

View File

@ -5,6 +5,7 @@ import (
"errors" "errors"
"fmt" "fmt"
"os" "os"
"strconv"
"strings" "strings"
"time" "time"
) )
@ -49,9 +50,17 @@ func (f *JSONFlattener) FlattenJSON(
return err return err
} }
} }
case []interface{}:
for i, v := range t {
k := strconv.Itoa(i)
err := f.FlattenJSON(fieldname+"_"+k+"_", v)
if err != nil {
return nil
}
}
case float64: case float64:
f.Fields[fieldname] = t f.Fields[fieldname] = t
case bool, string, []interface{}, nil: case bool, string, nil:
// ignored types // ignored types
return nil return nil
default: default:

View File

@ -562,6 +562,9 @@ var indicesExpected = map[string]interface{}{
} }
var osExpected = map[string]interface{}{ var osExpected = map[string]interface{}{
"load_average_0": float64(0.01),
"load_average_1": float64(0.04),
"load_average_2": float64(0.05),
"swap_used_in_bytes": float64(0), "swap_used_in_bytes": float64(0),
"swap_free_in_bytes": float64(487997440), "swap_free_in_bytes": float64(487997440),
"timestamp": float64(1436460392944), "timestamp": float64(1436460392944),
@ -724,10 +727,13 @@ var threadPoolExpected = map[string]interface{}{
} }
var fsExpected = map[string]interface{}{ var fsExpected = map[string]interface{}{
"timestamp": float64(1436460392946), "data_0_total_in_bytes": float64(19507089408),
"total_free_in_bytes": float64(16909316096), "data_0_free_in_bytes": float64(16909316096),
"total_available_in_bytes": float64(15894814720), "data_0_available_in_bytes": float64(15894814720),
"total_total_in_bytes": float64(19507089408), "timestamp": float64(1436460392946),
"total_free_in_bytes": float64(16909316096),
"total_available_in_bytes": float64(15894814720),
"total_total_in_bytes": float64(19507089408),
} }
var transportExpected = map[string]interface{}{ var transportExpected = map[string]interface{}{

View File

@ -59,13 +59,17 @@ func TestExec(t *testing.T) {
var acc testutil.Accumulator var acc testutil.Accumulator
err := e.Gather(&acc) err := e.Gather(&acc)
require.NoError(t, err) require.NoError(t, err)
assert.Equal(t, acc.NFields(), 4, "non-numeric measurements should be ignored") assert.Equal(t, acc.NFields(), 8, "non-numeric measurements should be ignored")
fields := map[string]interface{}{ fields := map[string]interface{}{
"num_processes": float64(82), "num_processes": float64(82),
"cpu_used": float64(8234), "cpu_used": float64(8234),
"cpu_free": float64(32), "cpu_free": float64(32),
"percent": float64(0.81), "percent": float64(0.81),
"users_0": float64(0),
"users_1": float64(1),
"users_2": float64(2),
"users_3": float64(3),
} }
acc.AssertContainsFields(t, "exec", fields) acc.AssertContainsFields(t, "exec", fields)
} }

View File

@ -19,12 +19,12 @@ const validJSON = `
}, },
"ignored_null": null, "ignored_null": null,
"integer": 4, "integer": 4,
"ignored_list": [3, 4], "list": [3, 4],
"ignored_parent": { "ignored_parent": {
"another_ignored_list": [4],
"another_ignored_null": null, "another_ignored_null": null,
"ignored_string": "hello, world!" "ignored_string": "hello, world!"
} },
"another_list": [4]
}` }`
const validJSONTags = ` const validJSONTags = `
@ -35,8 +35,11 @@ const validJSONTags = `
}` }`
var expectedFields = map[string]interface{}{ var expectedFields = map[string]interface{}{
"parent_child": float64(3), "parent_child": float64(3),
"integer": float64(4), "list_0": float64(3),
"list_1": float64(4),
"another_list_0": float64(4),
"integer": float64(4),
} }
const invalidJSON = "I don't think this is JSON" const invalidJSON = "I don't think this is JSON"
@ -123,7 +126,7 @@ func TestHttpJson200(t *testing.T) {
var acc testutil.Accumulator var acc testutil.Accumulator
err := service.Gather(&acc) err := service.Gather(&acc)
require.NoError(t, err) require.NoError(t, err)
assert.Equal(t, 4, acc.NFields()) assert.Equal(t, 10, acc.NFields())
for _, srv := range service.Servers { for _, srv := range service.Servers {
tags := map[string]string{"server": srv} tags := map[string]string{"server": srv}
mname := "httpjson_" + service.Name mname := "httpjson_" + service.Name