Explorar el Código

stackdriver: use group by fields to create default alias

Daniel Lee hace 7 años
padre
commit
8d1f293676

+ 20 - 7
pkg/tsdb/stackdriver/stackdriver.go

@@ -126,10 +126,17 @@ func (e *StackdriverExecutor) buildQueries(tsdbQuery *tsdb.TsdbQuery) ([]*Stackd
 			slog.Debug("Stackdriver request", "params", params)
 		}
 
+		groupBys := query.Model.Get("groupBys").MustArray()
+		groupBysAsStrings := make([]string, 0)
+		for _, groupBy := range groupBys {
+			groupBysAsStrings = append(groupBysAsStrings, groupBy.(string))
+		}
+
 		stackdriverQueries = append(stackdriverQueries, &StackdriverQuery{
-			Target: target,
-			Params: params,
-			RefID:  query.RefId,
+			Target:   target,
+			Params:   params,
+			RefID:    query.RefId,
+			GroupBys: groupBysAsStrings,
 		})
 	}
 
@@ -182,7 +189,6 @@ func (e *StackdriverExecutor) executeQuery(ctx context.Context, query *Stackdriv
 	}
 
 	req.URL.RawQuery = query.Params.Encode()
-	fmt.Println("req.URL.RawQuery: ", req.URL.RawQuery)
 	queryResult.Meta.Set("rawQuery", req.URL.RawQuery)
 
 	span, ctx := opentracing.StartSpanFromContext(ctx, "stackdriver query")
@@ -211,7 +217,7 @@ func (e *StackdriverExecutor) executeQuery(ctx context.Context, query *Stackdriv
 		return queryResult, nil
 	}
 
-	err = e.parseResponse(queryResult, data)
+	err = e.parseResponse(queryResult, data, query)
 	if err != nil {
 		queryResult.Error = err
 		return queryResult, nil
@@ -242,7 +248,7 @@ func (e *StackdriverExecutor) unmarshalResponse(res *http.Response) (Stackdriver
 	return data, nil
 }
 
-func (e *StackdriverExecutor) parseResponse(queryRes *tsdb.QueryResult, data StackdriverResponse) error {
+func (e *StackdriverExecutor) parseResponse(queryRes *tsdb.QueryResult, data StackdriverResponse, query *StackdriverQuery) error {
 	metricLabels := make(map[string][]string)
 	resourceLabels := make(map[string][]string)
 
@@ -260,13 +266,19 @@ func (e *StackdriverExecutor) parseResponse(queryRes *tsdb.QueryResult, data Sta
 			if !containsLabel(metricLabels[key], value) {
 				metricLabels[key] = append(metricLabels[key], value)
 			}
-			metricName += " " + value
+			if len(query.GroupBys) == 0 || containsLabel(query.GroupBys, "metric.label."+key) {
+				metricName += " " + value
+			}
 		}
 
 		for key, value := range series.Resource.Labels {
 			if !containsLabel(resourceLabels[key], value) {
 				resourceLabels[key] = append(resourceLabels[key], value)
 			}
+
+			if containsLabel(query.GroupBys, "resource.label."+key) {
+				metricName += " " + value
+			}
 		}
 
 		queryRes.Series = append(queryRes.Series, &tsdb.TimeSeries{
@@ -277,6 +289,7 @@ func (e *StackdriverExecutor) parseResponse(queryRes *tsdb.QueryResult, data Sta
 
 	queryRes.Meta.Set("resourceLabels", resourceLabels)
 	queryRes.Meta.Set("metricLabels", metricLabels)
+	queryRes.Meta.Set("groupBys", query.GroupBys)
 
 	return nil
 }

+ 40 - 12
pkg/tsdb/stackdriver/stackdriver_test.go

@@ -168,16 +168,13 @@ func TestStackdriver(t *testing.T) {
 
 		Convey("Parse stackdriver response in the time series format", func() {
 			Convey("when data from query aggregated to one time series", func() {
-				var data StackdriverResponse
-
-				jsonBody, err := ioutil.ReadFile("./test-data/1-series-response-agg-one-metric.json")
-				So(err, ShouldBeNil)
-				err = json.Unmarshal(jsonBody, &data)
+				data, err := loadTestFile("./test-data/1-series-response-agg-one-metric.json")
 				So(err, ShouldBeNil)
 				So(len(data.TimeSeries), ShouldEqual, 1)
 
 				res := &tsdb.QueryResult{Meta: simplejson.New(), RefId: "A"}
-				err = executor.parseResponse(res, data)
+				query := &StackdriverQuery{}
+				err = executor.parseResponse(res, data, query)
 				So(err, ShouldBeNil)
 
 				So(len(res.Series), ShouldEqual, 1)
@@ -197,16 +194,13 @@ func TestStackdriver(t *testing.T) {
 			})
 
 			Convey("when data from query with no aggregation", func() {
-				var data StackdriverResponse
-
-				jsonBody, err := ioutil.ReadFile("./test-data/2-series-response-no-agg.json")
-				So(err, ShouldBeNil)
-				err = json.Unmarshal(jsonBody, &data)
+				data, err := loadTestFile("./test-data/2-series-response-no-agg.json")
 				So(err, ShouldBeNil)
 				So(len(data.TimeSeries), ShouldEqual, 3)
 
 				res := &tsdb.QueryResult{Meta: simplejson.New(), RefId: "A"}
-				err = executor.parseResponse(res, data)
+				query := &StackdriverQuery{}
+				err = executor.parseResponse(res, data, query)
 				So(err, ShouldBeNil)
 
 				Convey("Should add labels to metric name", func() {
@@ -214,7 +208,9 @@ func TestStackdriver(t *testing.T) {
 					So(res.Series[0].Name, ShouldEqual, "compute.googleapis.com/instance/cpu/usage_time collector-asia-east-1")
 					So(res.Series[1].Name, ShouldEqual, "compute.googleapis.com/instance/cpu/usage_time collector-europe-west-1")
 					So(res.Series[2].Name, ShouldEqual, "compute.googleapis.com/instance/cpu/usage_time collector-us-east-1")
+				})
 
+				Convey("Should parse to time series", func() {
 					So(len(res.Series[0].Points), ShouldEqual, 3)
 					So(res.Series[0].Points[0][0].Float64, ShouldEqual, 9.8566497180145)
 					So(res.Series[0].Points[1][0].Float64, ShouldEqual, 9.7323568146676)
@@ -240,6 +236,38 @@ func TestStackdriver(t *testing.T) {
 					So(resourceLabels["project_id"][0], ShouldEqual, "grafana-prod")
 				})
 			})
+
+			Convey("when data from query with no aggregation and group bys", func() {
+				data, err := loadTestFile("./test-data/2-series-response-no-agg.json")
+				So(err, ShouldBeNil)
+				So(len(data.TimeSeries), ShouldEqual, 3)
+
+				res := &tsdb.QueryResult{Meta: simplejson.New(), RefId: "A"}
+				query := &StackdriverQuery{GroupBys: []string{"metric.label.instance_name", "resource.label.zone"}}
+				err = executor.parseResponse(res, data, query)
+				So(err, ShouldBeNil)
+
+				Convey("Should add instance name and zone labels to metric name", func() {
+					So(len(res.Series), ShouldEqual, 3)
+					So(res.Series[0].Name, ShouldEqual, "compute.googleapis.com/instance/cpu/usage_time collector-asia-east-1 asia-east1-a")
+					So(res.Series[1].Name, ShouldEqual, "compute.googleapis.com/instance/cpu/usage_time collector-europe-west-1 europe-west1-b")
+					So(res.Series[2].Name, ShouldEqual, "compute.googleapis.com/instance/cpu/usage_time collector-us-east-1 us-east1-b")
+				})
+			})
 		})
 	})
 }
+
+func loadTestFile(path string) (StackdriverResponse, error) {
+	var data StackdriverResponse
+
+	jsonBody, err := ioutil.ReadFile(path)
+	if err != nil {
+		return data, err
+	}
+	err = json.Unmarshal(jsonBody, &data)
+	if err != nil {
+		return data, err
+	}
+	return data, nil
+}

+ 4 - 3
pkg/tsdb/stackdriver/types.go

@@ -6,9 +6,10 @@ import (
 )
 
 type StackdriverQuery struct {
-	Target string
-	Params url.Values
-	RefID  string
+	Target   string
+	Params   url.Values
+	RefID    string
+	GroupBys []string
 }
 
 type StackdriverResponse struct {