initial jsonpath functionality
This commit is contained in:
parent
23523ffd10
commit
342d3d633a
|
@ -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
|
||||
}
|
|
@ -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()
|
||||
|
||||
}
|
Loading…
Reference in New Issue