diff --git a/pkg/tsdb/cloudwatch/cloudwatch_query.go b/pkg/tsdb/cloudwatch/cloudwatch_query.go index a5c7176dc96..51f6b1c19c9 100644 --- a/pkg/tsdb/cloudwatch/cloudwatch_query.go +++ b/pkg/tsdb/cloudwatch/cloudwatch_query.go @@ -102,7 +102,7 @@ func (q *cloudWatchQuery) isMultiValuedDimensionExpression() bool { return false } -func (q *cloudWatchQuery) buildDeepLink(startTime time.Time, endTime time.Time) (string, error) { +func (q *cloudWatchQuery) buildDeepLink(startTime time.Time, endTime time.Time, dynamicLabelEnabled bool) (string, error) { if q.isMathExpression() || q.MetricQueryType == MetricQueryTypeQuery { return "", nil } @@ -117,16 +117,24 @@ func (q *cloudWatchQuery) buildDeepLink(startTime time.Time, endTime time.Time) } if q.isSearchExpression() { - link.Metrics = []interface{}{&metricExpression{Expression: q.UsedExpression}} + metricExpressions := &metricExpression{Expression: q.UsedExpression} + if dynamicLabelEnabled { + metricExpressions.Label = q.Label + } + link.Metrics = []interface{}{metricExpressions} } else { metricStat := []interface{}{q.Namespace, q.MetricName} for dimensionKey, dimensionValues := range q.Dimensions { metricStat = append(metricStat, dimensionKey, dimensionValues[0]) } - metricStat = append(metricStat, &metricStatMeta{ + metricStatMeta := &metricStatMeta{ Stat: q.Statistic, Period: q.Period, - }) + } + if dynamicLabelEnabled { + metricStatMeta.Label = q.Label + } + metricStat = append(metricStat, metricStatMeta) link.Metrics = []interface{}{metricStat} } diff --git a/pkg/tsdb/cloudwatch/cloudwatch_query_test.go b/pkg/tsdb/cloudwatch/cloudwatch_query_test.go index 035e808fdd0..7fe0a10d1e3 100644 --- a/pkg/tsdb/cloudwatch/cloudwatch_query_test.go +++ b/pkg/tsdb/cloudwatch/cloudwatch_query_test.go @@ -9,27 +9,98 @@ import ( ) func TestCloudWatchQuery(t *testing.T) { - t.Run("Deeplink is not generated for MetricQueryTypeQuery", func(t *testing.T) { - startTime := time.Now() - endTime := startTime.Add(2 * time.Hour) - query := &cloudWatchQuery{ - RefId: "A", - Region: "us-east-1", - Expression: "", - Statistic: "Average", - Period: 300, - Id: "id1", - MatchExact: true, - Dimensions: map[string][]string{ - "InstanceId": {"i-12345678"}, - }, - MetricQueryType: MetricQueryTypeQuery, - MetricEditorMode: MetricEditorModeBuilder, - } + t.Run("Deeplink", func(t *testing.T) { + t.Run("is not generated for MetricQueryTypeQuery", func(t *testing.T) { + startTime := time.Now() + endTime := startTime.Add(2 * time.Hour) + query := &cloudWatchQuery{ + RefId: "A", + Region: "us-east-1", + Expression: "", + Statistic: "Average", + Period: 300, + Id: "id1", + MatchExact: true, + Dimensions: map[string][]string{ + "InstanceId": {"i-12345678"}, + }, + MetricQueryType: MetricQueryTypeQuery, + MetricEditorMode: MetricEditorModeBuilder, + } - deepLink, err := query.buildDeepLink(startTime, endTime) - require.NoError(t, err) - assert.Empty(t, deepLink) + deepLink, err := query.buildDeepLink(startTime, endTime, false) + require.NoError(t, err) + assert.Empty(t, deepLink) + }) + + t.Run("does not include label in case dynamic label is diabled", func(t *testing.T) { + startTime := time.Now() + endTime := startTime.Add(2 * time.Hour) + query := &cloudWatchQuery{ + RefId: "A", + Region: "us-east-1", + Expression: "", + Statistic: "Average", + Period: 300, + Id: "id1", + MatchExact: true, + Label: "${PROP('Namespace')}", + Dimensions: map[string][]string{ + "InstanceId": {"i-12345678"}, + }, + MetricQueryType: MetricQueryTypeSearch, + MetricEditorMode: MetricEditorModeBuilder, + } + + deepLink, err := query.buildDeepLink(startTime, endTime, false) + require.NoError(t, err) + assert.NotContains(t, deepLink, "label") + }) + + t.Run("includes label in case dynamic label is enabled and it's a metric stat query", func(t *testing.T) { + startTime := time.Now() + endTime := startTime.Add(2 * time.Hour) + query := &cloudWatchQuery{ + RefId: "A", + Region: "us-east-1", + Expression: "", + Statistic: "Average", + Period: 300, + Id: "id1", + MatchExact: true, + Label: "${PROP('Namespace')}", + Dimensions: map[string][]string{ + "InstanceId": {"i-12345678"}, + }, + MetricQueryType: MetricQueryTypeSearch, + MetricEditorMode: MetricEditorModeBuilder, + } + + deepLink, err := query.buildDeepLink(startTime, endTime, false) + require.NoError(t, err) + assert.NotContains(t, deepLink, "label") + }) + + t.Run("includes label in case dynamic label is enabled and it's a math expression query", func(t *testing.T) { + startTime := time.Now() + endTime := startTime.Add(2 * time.Hour) + query := &cloudWatchQuery{ + RefId: "A", + Region: "us-east-1", + Statistic: "Average", + Expression: "SEARCH(someexpression)", + Period: 300, + Id: "id1", + MatchExact: true, + Label: "${PROP('Namespace')}", + MetricQueryType: MetricQueryTypeSearch, + MetricEditorMode: MetricEditorModeRaw, + } + + deepLink, err := query.buildDeepLink(startTime, endTime, false) + require.NoError(t, err) + assert.NotContains(t, deepLink, "label") + }) }) t.Run("SEARCH(someexpression) was specified in the query editor", func(t *testing.T) { diff --git a/pkg/tsdb/cloudwatch/response_parser.go b/pkg/tsdb/cloudwatch/response_parser.go index c91b6f03985..41a24c2148e 100644 --- a/pkg/tsdb/cloudwatch/response_parser.go +++ b/pkg/tsdb/cloudwatch/response_parser.go @@ -118,7 +118,7 @@ func buildDataFrames(startTime time.Time, endTime time.Time, aggregatedResponse for _, metric := range aggregatedResponse.Metrics { label := *metric.Label - deepLink, err := query.buildDeepLink(startTime, endTime) + deepLink, err := query.buildDeepLink(startTime, endTime, dynamicLabelEnabled) if err != nil { return nil, err } diff --git a/pkg/tsdb/cloudwatch/types.go b/pkg/tsdb/cloudwatch/types.go index 1c7bb1d9995..c32967fd341 100644 --- a/pkg/tsdb/cloudwatch/types.go +++ b/pkg/tsdb/cloudwatch/types.go @@ -25,11 +25,13 @@ type cloudWatchLink struct { type metricExpression struct { Expression string `json:"expression"` + Label string `json:"label,omitempty"` } type metricStatMeta struct { Stat string `json:"stat"` Period int `json:"period"` + Label string `json:"label,omitempty"` } type metricQueryType uint32