diff --git a/pkg/tsdb/cloudwatch/response_parser.go b/pkg/tsdb/cloudwatch/response_parser.go index b9248fbcd29..bb3310db73e 100644 --- a/pkg/tsdb/cloudwatch/response_parser.go +++ b/pkg/tsdb/cloudwatch/response_parser.go @@ -105,9 +105,11 @@ func parseLabels(cloudwatchLabel string, query *models.CloudWatchQuery) (string, splitLabels := strings.Split(cloudwatchLabel, keySeparator) // The first part is the name of the time series, followed by the labels + name := splitLabels[0] labelsIndex := 1 - labels := data.Labels{} + // set Series to the name of the time series as a fallback + labels := data.Labels{"Series": name} for _, dim := range dims { values := query.Dimensions[dim] if isSingleValue(values) { @@ -118,7 +120,7 @@ func parseLabels(cloudwatchLabel string, query *models.CloudWatchQuery) (string, labels[dim] = splitLabels[labelsIndex] labelsIndex++ } - return splitLabels[0], labels + return name, labels } func getLabels(cloudwatchLabel string, query *models.CloudWatchQuery, addSeriesLabelAsFallback bool) data.Labels { diff --git a/pkg/tsdb/cloudwatch/response_parser_test.go b/pkg/tsdb/cloudwatch/response_parser_test.go index b356099922e..b9ee587ef48 100644 --- a/pkg/tsdb/cloudwatch/response_parser_test.go +++ b/pkg/tsdb/cloudwatch/response_parser_test.go @@ -207,11 +207,13 @@ func Test_buildDataFrames_parse_label_to_name_and_labels(t *testing.T) { frame1 := frames[0] assert.Equal(t, "lb1", frame1.Name) + assert.Equal(t, "lb1", frame1.Fields[1].Labels["Series"]) assert.Equal(t, "lb1", frame1.Fields[1].Labels["LoadBalancer"]) assert.Equal(t, "tg", frame1.Fields[1].Labels["TargetGroup"]) frame2 := frames[1] assert.Equal(t, "lb2", frame2.Name) + assert.Equal(t, "lb2", frame2.Fields[1].Labels["Series"]) assert.Equal(t, "lb2", frame2.Fields[1].Labels["LoadBalancer"]) assert.Equal(t, "tg", frame2.Fields[1].Labels["TargetGroup"]) }) @@ -272,11 +274,13 @@ func Test_buildDataFrames_parse_label_to_name_and_labels(t *testing.T) { require.NoError(t, err) assert.Equal(t, "some label lb3", frames[0].Name) + assert.Equal(t, "some label lb3", frames[0].Fields[1].Labels["Series"]) assert.Equal(t, "balancer 1", frames[0].Fields[1].Labels["LoadBalancer"]) assert.Equal(t, "inst1", frames[0].Fields[1].Labels["InstanceType"]) assert.Equal(t, "tg", frames[0].Fields[1].Labels["TargetGroup"]) assert.Equal(t, "some label lb4", frames[1].Name) + assert.Equal(t, "some label lb4", frames[1].Fields[1].Labels["Series"]) assert.Equal(t, "balancer 2", frames[1].Fields[1].Labels["LoadBalancer"]) assert.Equal(t, "inst2", frames[1].Fields[1].Labels["InstanceType"]) assert.Equal(t, "tg", frames[1].Fields[1].Labels["TargetGroup"]) @@ -494,6 +498,42 @@ func Test_buildDataFrames_parse_label_to_name_and_labels(t *testing.T) { assert.Equal(t, "res", frames[0].Fields[1].Labels["Resource"]) }) + t.Run("when code editor used for `MetricSearch` query add fallback label", func(t *testing.T) { + timestamp := time.Unix(0, 0) + response := &models.QueryRowResponse{ + Metrics: []*cloudwatch.MetricDataResult{ + { + Id: aws.String("lb3"), + Label: aws.String("some label"), + Timestamps: []*time.Time{ + aws.Time(timestamp), + }, + Values: []*float64{aws.Float64(23)}, + StatusCode: aws.String("Complete"), + }, + }, + } + + query := &models.CloudWatchQuery{ + RefId: "refId1", + Region: "us-east-1", + Namespace: "", + MetricName: "", + Expression: "SEARCH('MetricName=\"ResourceCount\" AND (\"AWS/Usage\") AND Resource=TargetsPer NOT QueueName=TargetsPerNetworkLoadBalancer', 'Average')", + Dimensions: map[string][]string{}, + Statistic: "Average", + Period: 60, + MetricQueryType: models.MetricQueryTypeSearch, + MetricEditorMode: models.MetricEditorModeRaw, + Label: "actual", + } + frames, err := buildDataFrames(contextWithFeaturesEnabled(features.FlagCloudWatchNewLabelParsing), startTime, endTime, *response, query) + require.NoError(t, err) + + assert.Equal(t, "actual", frames[0].Name) + assert.Equal(t, "some label", frames[0].Fields[1].Labels["Series"]) + }) + t.Run("when `MetricQuery` query has no label set and `GROUP BY` clause has multiple fields", func(t *testing.T) { timestamp := time.Unix(0, 0) response := &models.QueryRowResponse{