initial jsonpath functionality

This commit is contained in:
Max U 2018-06-28 14:33:38 -07:00
parent 23523ffd10
commit 342d3d633a
2 changed files with 115 additions and 0 deletions

View File

@ -0,0 +1,76 @@
package jsonpath
import (
"encoding/json"
"log"
"reflect"
"strconv"
"time"
"github.com/influxdata/telegraf"
"github.com/influxdata/telegraf/metric"
"github.com/jsonpath"
)
type JSONPath struct {
MetricName string
TagPath map[string]string
FieldPath map[string]string
}
func (j *JSONPath) Parse(buf []byte) ([]telegraf.Metric, error) {
tags := make(map[string]string)
fields := make(map[string]interface{})
metrics := make([]telegraf.Metric, 0)
//turn buf into json interface
var jsonData interface{}
json.Unmarshal(buf, &jsonData)
log.Printf("unmarshaled jsonData: %v", jsonData)
for k, v := range j.TagPath {
c, err := jsonpath.JsonPathLookup(jsonData, v)
if err != nil {
log.Printf("E! Could not find JSON Path: %v", v)
}
cType := reflect.TypeOf(c)
//if path returns multiple values, split each into a different metric
if cType.Kind() == reflect.Array {
log.Printf("E! Multiple return values for path: %v", v)
continue
}
switch ct := c.(type) {
case string:
tags[k] = ct
case bool:
tags[k] = strconv.FormatBool(ct)
case float64:
tags[k] = strconv.FormatFloat(ct, 'f', -1, 64)
default:
log.Printf("E! [parsers.json] Unrecognized type %T", ct)
}
}
for k, v := range j.FieldPath {
c, err := jsonpath.JsonPathLookup(jsonData, v)
if err != nil {
log.Printf("E! Could not find JSON Path: %v", v)
continue
}
cType := reflect.TypeOf(c)
//if path returns multiple values, split each into a different metric
if cType.Kind() == reflect.Array {
log.Printf("E! Multiple return values for path: %v", v)
continue
}
fields[k] = c
}
m, _ := metric.New(j.MetricName, tags, fields, time.Now())
metrics = append(metrics, m)
return metrics, nil
}

View File

@ -0,0 +1,39 @@
package jsonpath
import (
"log"
"testing"
"github.com/stretchr/testify/assert"
)
func TestParseJsonPath(t *testing.T) {
testString := `{
"total_devices": 5,
"total_threads": 10,
"shares": {
"total": 5,
"accepted": 5,
"rejected": 0,
"avg_find_time": 4,
"tester": "work",
"tester2": "don't want this",
"tester3": {
"hello":"sup",
"fun":"money",
"break":9
}
}
}`
jsonParser := JSONPath{
MetricName: "jsonpather",
TagPath: map[string]string{"total": "$.shares.tester3"},
}
metrics, err := jsonParser.Parse([]byte(testString))
assert.NoError(t, err)
log.Printf("m[0] name: %v, tags: %v, fields: %v", metrics[0].Name(), metrics[0].Tags(), metrics[0].Fields())
t.Error()
}