CloudWatch: Fix labels for raw metric search queries (#88943)

This commit is contained in:
Isabella Siu 2024-06-07 17:37:19 -04:00 committed by GitHub
parent 7ca3ec7518
commit 114a136378
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 44 additions and 2 deletions

View File

@ -105,9 +105,11 @@ func parseLabels(cloudwatchLabel string, query *models.CloudWatchQuery) (string,
splitLabels := strings.Split(cloudwatchLabel, keySeparator) splitLabels := strings.Split(cloudwatchLabel, keySeparator)
// The first part is the name of the time series, followed by the labels // The first part is the name of the time series, followed by the labels
name := splitLabels[0]
labelsIndex := 1 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 { for _, dim := range dims {
values := query.Dimensions[dim] values := query.Dimensions[dim]
if isSingleValue(values) { if isSingleValue(values) {
@ -118,7 +120,7 @@ func parseLabels(cloudwatchLabel string, query *models.CloudWatchQuery) (string,
labels[dim] = splitLabels[labelsIndex] labels[dim] = splitLabels[labelsIndex]
labelsIndex++ labelsIndex++
} }
return splitLabels[0], labels return name, labels
} }
func getLabels(cloudwatchLabel string, query *models.CloudWatchQuery, addSeriesLabelAsFallback bool) data.Labels { func getLabels(cloudwatchLabel string, query *models.CloudWatchQuery, addSeriesLabelAsFallback bool) data.Labels {

View File

@ -207,11 +207,13 @@ func Test_buildDataFrames_parse_label_to_name_and_labels(t *testing.T) {
frame1 := frames[0] frame1 := frames[0]
assert.Equal(t, "lb1", frame1.Name) 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, "lb1", frame1.Fields[1].Labels["LoadBalancer"])
assert.Equal(t, "tg", frame1.Fields[1].Labels["TargetGroup"]) assert.Equal(t, "tg", frame1.Fields[1].Labels["TargetGroup"])
frame2 := frames[1] frame2 := frames[1]
assert.Equal(t, "lb2", frame2.Name) 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, "lb2", frame2.Fields[1].Labels["LoadBalancer"])
assert.Equal(t, "tg", frame2.Fields[1].Labels["TargetGroup"]) 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) require.NoError(t, err)
assert.Equal(t, "some label lb3", frames[0].Name) 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, "balancer 1", frames[0].Fields[1].Labels["LoadBalancer"])
assert.Equal(t, "inst1", frames[0].Fields[1].Labels["InstanceType"]) assert.Equal(t, "inst1", frames[0].Fields[1].Labels["InstanceType"])
assert.Equal(t, "tg", frames[0].Fields[1].Labels["TargetGroup"]) 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].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, "balancer 2", frames[1].Fields[1].Labels["LoadBalancer"])
assert.Equal(t, "inst2", frames[1].Fields[1].Labels["InstanceType"]) assert.Equal(t, "inst2", frames[1].Fields[1].Labels["InstanceType"])
assert.Equal(t, "tg", frames[1].Fields[1].Labels["TargetGroup"]) 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"]) 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) { 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) timestamp := time.Unix(0, 0)
response := &models.QueryRowResponse{ response := &models.QueryRowResponse{