From d4a4ac25bb18f91ba3deace35bca03f31d694790 Mon Sep 17 00:00:00 2001 From: Max U Date: Mon, 2 Jul 2018 11:20:16 -0700 Subject: [PATCH] add option to mark field as int --- internal/config/config.go | 14 ++++++++++++ plugins/parsers/gjson/parser.go | 18 +++++++++++---- plugins/parsers/gjson/parser_test.go | 33 ++++++++++++++++++++++++++++ plugins/parsers/registry.go | 22 +++++++++++-------- 4 files changed, 74 insertions(+), 13 deletions(-) diff --git a/internal/config/config.go b/internal/config/config.go index aa09e66e0..9f99516a7 100644 --- a/internal/config/config.go +++ b/internal/config/config.go @@ -1390,6 +1390,19 @@ func buildParser(name string, tbl *ast.Table) (parsers.Parser, error) { } } + c.GJSONIntPaths = make(map[string]string) + if node, ok := tbl.Fields["gjson_int_paths"]; ok { + if subtbl, ok := node.(*ast.Table); ok { + for name, val := range subtbl.Fields { + if kv, ok := val.(*ast.KeyValue); ok { + if str, ok := kv.Value.(*ast.String); ok { + c.GJSONIntPaths[name] = str.Value + } + } + } + } + } + c.MetricName = name delete(tbl.Fields, "data_format") @@ -1409,6 +1422,7 @@ func buildParser(name string, tbl *ast.Table) (parsers.Parser, error) { delete(tbl.Fields, "gjson_bool_paths") delete(tbl.Fields, "gjson_float_paths") delete(tbl.Fields, "gjson_string_paths") + delete(tbl.Fields, "gjson_int_paths") return parsers.NewParser(c) } diff --git a/plugins/parsers/gjson/parser.go b/plugins/parsers/gjson/parser.go index 56badb61c..9618aadea 100644 --- a/plugins/parsers/gjson/parser.go +++ b/plugins/parsers/gjson/parser.go @@ -13,24 +13,34 @@ type JSONPath struct { MetricName string TagPath map[string]string FloatPath map[string]string + IntPath map[string]string StrPath map[string]string BoolPath map[string]string DefaultTags map[string]string } func (j *JSONPath) Parse(buf []byte) ([]telegraf.Metric, error) { - tags := j.DefaultTags + tags := make(map[string]string) + for k, v := range j.DefaultTags { + tags[k] = v + } fields := make(map[string]interface{}) metrics := make([]telegraf.Metric, 0) for k, v := range j.TagPath { c := gjson.GetBytes(buf, v) - tags[k] = c.Str + tags[k] = c.String() } for k, v := range j.FloatPath { c := gjson.GetBytes(buf, v) - fields[k] = c.Num + fields[k] = c.Float() + } + + for k, v := range j.IntPath { + c := gjson.GetBytes(buf, v) + fields[k] = c.Int() + log.Printf("got a int: fields[%v]: %v", k, c.Int()) } for k, v := range j.BoolPath { @@ -46,7 +56,7 @@ func (j *JSONPath) Parse(buf []byte) ([]telegraf.Metric, error) { for k, v := range j.StrPath { c := gjson.GetBytes(buf, v) - fields[k] = c.Str + fields[k] = c.String() } m, err := metric.New(j.MetricName, tags, fields, time.Now()) diff --git a/plugins/parsers/gjson/parser_test.go b/plugins/parsers/gjson/parser_test.go index c56288556..81e3cf49c 100644 --- a/plugins/parsers/gjson/parser_test.go +++ b/plugins/parsers/gjson/parser_test.go @@ -2,6 +2,7 @@ package gjson import ( "log" + "reflect" "testing" "github.com/stretchr/testify/assert" @@ -38,3 +39,35 @@ func TestParseJsonPath(t *testing.T) { t.Error() } + +func TestTagTypes(t *testing.T) { + testString := `{ + "total_devices": 5, + "total_threads": 10, + "shares": { + "total": 5, + "accepted": 5, + "rejected": 0, + "my_bool": true, + "tester": "work", + "tester2": { + "hello":"sup", + "fun":true, + "break":9.97 + } + } + }` + + r := JSONPath{ + TagPath: map[string]string{"int1": "total_devices", "my_bool": "shares.my_bool"}, + FloatPath: map[string]string{"total": "shares.total"}, + BoolPath: map[string]string{"fun": "shares.tester2.fun"}, + StrPath: map[string]string{"hello": "shares.tester2.hello"}, + IntPath: map[string]string{"accepted": "shares.accepted"}, + } + + metrics, err := r.Parse([]byte(testString)) + log.Printf("m[0] name: %v, tags: %v, fields: %v", metrics[0].Name(), metrics[0].Tags(), metrics[0].Fields()) + assert.NoError(t, err) + assert.Equal(t, true, reflect.DeepEqual(map[string]interface{}{"total": 5.0, "fun": true, "hello": "sup", "accepted": int64(5)}, metrics[0].Fields())) +} diff --git a/plugins/parsers/registry.go b/plugins/parsers/registry.go index 4ff13e770..84da84ac0 100644 --- a/plugins/parsers/registry.go +++ b/plugins/parsers/registry.go @@ -90,10 +90,11 @@ type Config struct { DropwizardTagPathsMap map[string]string //for gjson format - TagPaths map[string]string - BoolPaths map[string]string - FloatPaths map[string]string - StringPaths map[string]string + GJSONTagPaths map[string]string + GJSONBoolPaths map[string]string + GJSONFloatPaths map[string]string + GJSONStringPaths map[string]string + GJSONIntPaths map[string]string } // NewParser returns a Parser interface based on the given config. @@ -130,10 +131,11 @@ func NewParser(config *Config) (Parser, error) { case "gjson": parser, err = newGJSONParser(config.MetricName, - config.TagPaths, - config.StringPaths, - config.BoolPaths, - config.FloatPaths) + config.GJSONTagPaths, + config.GJSONStringPaths, + config.GJSONBoolPaths, + config.GJSONFloatPaths, + config.GJSONIntPaths) default: err = fmt.Errorf("Invalid data format: %s", config.DataFormat) } @@ -144,13 +146,15 @@ func newGJSONParser(metricName string, tagPaths map[string]string, strPaths map[string]string, boolPaths map[string]string, - floatPaths map[string]string) (Parser, error) { + floatPaths map[string]string, + intPaths map[string]string) (Parser, error) { parser := &gjson.JSONPath{ MetricName: metricName, TagPath: tagPaths, StrPath: strPaths, BoolPath: boolPaths, FloatPath: floatPaths, + IntPath: intPaths, } return parser, nil }