add option to mark field as int

This commit is contained in:
Max U 2018-07-02 11:20:16 -07:00
parent 92e156c784
commit d4a4ac25bb
4 changed files with 74 additions and 13 deletions

View File

@ -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 c.MetricName = name
delete(tbl.Fields, "data_format") 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_bool_paths")
delete(tbl.Fields, "gjson_float_paths") delete(tbl.Fields, "gjson_float_paths")
delete(tbl.Fields, "gjson_string_paths") delete(tbl.Fields, "gjson_string_paths")
delete(tbl.Fields, "gjson_int_paths")
return parsers.NewParser(c) return parsers.NewParser(c)
} }

View File

@ -13,24 +13,34 @@ type JSONPath struct {
MetricName string MetricName string
TagPath map[string]string TagPath map[string]string
FloatPath map[string]string FloatPath map[string]string
IntPath map[string]string
StrPath map[string]string StrPath map[string]string
BoolPath map[string]string BoolPath map[string]string
DefaultTags map[string]string DefaultTags map[string]string
} }
func (j *JSONPath) Parse(buf []byte) ([]telegraf.Metric, error) { 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{}) fields := make(map[string]interface{})
metrics := make([]telegraf.Metric, 0) metrics := make([]telegraf.Metric, 0)
for k, v := range j.TagPath { for k, v := range j.TagPath {
c := gjson.GetBytes(buf, v) c := gjson.GetBytes(buf, v)
tags[k] = c.Str tags[k] = c.String()
} }
for k, v := range j.FloatPath { for k, v := range j.FloatPath {
c := gjson.GetBytes(buf, v) 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 { 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 { for k, v := range j.StrPath {
c := gjson.GetBytes(buf, v) c := gjson.GetBytes(buf, v)
fields[k] = c.Str fields[k] = c.String()
} }
m, err := metric.New(j.MetricName, tags, fields, time.Now()) m, err := metric.New(j.MetricName, tags, fields, time.Now())

View File

@ -2,6 +2,7 @@ package gjson
import ( import (
"log" "log"
"reflect"
"testing" "testing"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
@ -38,3 +39,35 @@ func TestParseJsonPath(t *testing.T) {
t.Error() 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()))
}

View File

@ -90,10 +90,11 @@ type Config struct {
DropwizardTagPathsMap map[string]string DropwizardTagPathsMap map[string]string
//for gjson format //for gjson format
TagPaths map[string]string GJSONTagPaths map[string]string
BoolPaths map[string]string GJSONBoolPaths map[string]string
FloatPaths map[string]string GJSONFloatPaths map[string]string
StringPaths map[string]string GJSONStringPaths map[string]string
GJSONIntPaths map[string]string
} }
// NewParser returns a Parser interface based on the given config. // NewParser returns a Parser interface based on the given config.
@ -130,10 +131,11 @@ func NewParser(config *Config) (Parser, error) {
case "gjson": case "gjson":
parser, err = newGJSONParser(config.MetricName, parser, err = newGJSONParser(config.MetricName,
config.TagPaths, config.GJSONTagPaths,
config.StringPaths, config.GJSONStringPaths,
config.BoolPaths, config.GJSONBoolPaths,
config.FloatPaths) config.GJSONFloatPaths,
config.GJSONIntPaths)
default: default:
err = fmt.Errorf("Invalid data format: %s", config.DataFormat) err = fmt.Errorf("Invalid data format: %s", config.DataFormat)
} }
@ -144,13 +146,15 @@ func newGJSONParser(metricName string,
tagPaths map[string]string, tagPaths map[string]string,
strPaths map[string]string, strPaths map[string]string,
boolPaths 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{ parser := &gjson.JSONPath{
MetricName: metricName, MetricName: metricName,
TagPath: tagPaths, TagPath: tagPaths,
StrPath: strPaths, StrPath: strPaths,
BoolPath: boolPaths, BoolPath: boolPaths,
FloatPath: floatPaths, FloatPath: floatPaths,
IntPath: intPaths,
} }
return parser, nil return parser, nil
} }