@@ -0,0 +1,111 @@
|
||||
package elasticsearch
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"github.com/grafana/grafana/pkg/components/null"
|
||||
"github.com/grafana/grafana/pkg/components/simplejson"
|
||||
"github.com/grafana/grafana/pkg/tsdb"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
type ElasticsearchResponseParser struct {
|
||||
Responses []Response
|
||||
Targets []QueryBuilder
|
||||
}
|
||||
|
||||
func (rp *ElasticsearchResponseParser) getTimeSeries() []interface{} {
|
||||
for i, res := range rp.Responses {
|
||||
var series []interface{}
|
||||
target := rp.Targets[i]
|
||||
props := make(map[string]interface{})
|
||||
rp.processBuckets(res.Aggregations, target, &series, props, 0)
|
||||
}
|
||||
}
|
||||
|
||||
func findAgg(target QueryBuilder, aggId string) (*simplejson.Json, error) {
|
||||
for _, v := range target.BucketAggs {
|
||||
aggDef := simplejson.NewFromAny(v)
|
||||
if aggId == aggDef.Get("id").MustString() {
|
||||
return aggDef, nil
|
||||
}
|
||||
}
|
||||
return nil, errors.New("can't found aggDef, aggID:" + aggId)
|
||||
}
|
||||
|
||||
func (rp *ElasticsearchResponseParser) processBuckets(aggs map[string]interface{}, target QueryBuilder, series *[]interface{}, props map[string]interface{}, depth int) error {
|
||||
maxDepth := len(target.BucketAggs) - 1
|
||||
for aggId, v := range aggs {
|
||||
aggDef, _ := findAgg(target, aggId)
|
||||
esAgg := simplejson.NewFromAny(v)
|
||||
if aggDef == nil {
|
||||
continue
|
||||
}
|
||||
|
||||
if depth == maxDepth {
|
||||
if aggDef.Get("type").MustString() == "date_histogram" {
|
||||
rp.processMetrics(esAgg, target, series, props)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func mapCopy(originalMap, newMap *map[string]string) {
|
||||
for k, v := range originalMap {
|
||||
newMap[k] = v
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func (rp *ElasticsearchResponseParser) processMetrics(esAgg *simplejson.Json, target QueryBuilder, props map[string]string) ([]*tsdb.TimeSeries, error) {
|
||||
var series []*tsdb.TimeSeries
|
||||
for _, v := range target.Metrics {
|
||||
metric := simplejson.NewFromAny(v)
|
||||
if metric.Get("hide").MustBool(false) {
|
||||
continue
|
||||
}
|
||||
metricId := fmt.Sprintf("%d", metric.Get("id").MustInt())
|
||||
metricField := metric.Get("field").MustString()
|
||||
|
||||
switch metric.Get("type").MustString() {
|
||||
case "count":
|
||||
newSeries := tsdb.TimeSeries{}
|
||||
for _, v := range esAgg.Get("buckets").MustMap() {
|
||||
bucket := simplejson.NewFromAny(v)
|
||||
value := bucket.Get("doc_count").MustFloat64()
|
||||
key := bucket.Get("key").MustFloat64()
|
||||
newSeries.Points = append(newSeries.Points, tsdb.TimePoint{null.FloatFromPtr(&value), null.FloatFromPtr(&key)})
|
||||
}
|
||||
newSeries.Tags = props
|
||||
newSeries.Tags["metric"] = "count"
|
||||
series = append(series, &newSeries)
|
||||
|
||||
case "percentiles":
|
||||
buckets := esAgg.Get("buckets").MustArray()
|
||||
if len(buckets) == 0 {
|
||||
break
|
||||
}
|
||||
|
||||
firstBucket := simplejson.NewFromAny(buckets[0])
|
||||
percentiles := firstBucket.GetPath(metricId, "values").MustMap()
|
||||
|
||||
for percentileName := range percentiles {
|
||||
newSeries := tsdb.TimeSeries{}
|
||||
newSeries.Tags = props
|
||||
newSeries.Tags["metric"] = "p" + percentileName
|
||||
newSeries.Tags["field"] = metricField
|
||||
for _, v := range buckets {
|
||||
bucket := simplejson.NewFromAny(v)
|
||||
valueStr := bucket.GetPath(metricId, "values", percentileName).MustString()
|
||||
value, _ := strconv.ParseFloat(valueStr, 64)
|
||||
key := bucket.Get("key").MustFloat64()
|
||||
newSeries.Points = append(newSeries.Points, tsdb.TimePoint{null.FloatFromPtr(&value), null.FloatFromPtr(&key)})
|
||||
}
|
||||
series = append(series, &newSeries)
|
||||
}
|
||||
}
|
||||
}
|
||||
return series
|
||||
}
|
||||
Reference in New Issue
Block a user