Cloudwatch: Round up endTime in GetMetricData to next minute (#89341)

* Add cloudWatchRoundUpEndTime feature toggle
This commit is contained in:
Ida Štambuk
2024-06-27 17:10:28 +02:00
committed by GitHub
parent 0aaf820fd9
commit ba5b33227c
9 changed files with 56 additions and 2 deletions
+1
View File
@@ -10,6 +10,7 @@ const (
FlagCloudWatchCrossAccountQuerying = "cloudWatchCrossAccountQuerying"
FlagCloudWatchBatchQueries = "cloudWatchBatchQueries"
FlagCloudWatchNewLabelParsing = "cloudWatchNewLabelParsing"
FlagCloudWatchRoundUpEndTime = "cloudWatchRoundUpEndTime"
)
func IsEnabled(ctx context.Context, feature string) bool {
@@ -2,10 +2,12 @@ package cloudwatch
import (
"context"
"time"
"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/service/cloudwatch"
"github.com/aws/aws-sdk-go/service/cloudwatch/cloudwatchiface"
"github.com/grafana/grafana/pkg/tsdb/cloudwatch/features"
"github.com/grafana/grafana/pkg/tsdb/cloudwatch/utils"
)
@@ -18,6 +20,11 @@ func (e *cloudWatchExecutor) executeRequest(ctx context.Context, client cloudwat
if nextToken != "" {
metricDataInput.NextToken = aws.String(nextToken)
}
// GetMetricData EndTime is exclusive, so we round up to the next minute to get the last data point
if features.IsEnabled(ctx, features.FlagCloudWatchRoundUpEndTime) {
*metricDataInput.EndTime = metricDataInput.EndTime.Truncate(time.Minute).Add(time.Minute)
}
resp, err := client.GetMetricDataWithContext(ctx, metricDataInput)
if err != nil {
return mdo, err
@@ -3,18 +3,38 @@ package cloudwatch
import (
"context"
"testing"
"time"
"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/service/cloudwatch"
"github.com/grafana/grafana/pkg/tsdb/cloudwatch/features"
"github.com/grafana/grafana/pkg/tsdb/cloudwatch/mocks"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/mock"
"github.com/stretchr/testify/require"
)
func TestGetMetricDataExecutorTest(t *testing.T) {
func TestGetMetricDataExecutorTestRequest(t *testing.T) {
t.Run("Should round up end time if cloudWatchRoundUpEndTime is enabled", func(t *testing.T) {
executor := &cloudWatchExecutor{}
queryEndTime, _ := time.Parse("2006-01-02T15:04:05Z07:00", "2024-05-01T01:45:04Z")
inputs := &cloudwatch.GetMetricDataInput{EndTime: &queryEndTime, MetricDataQueries: []*cloudwatch.MetricDataQuery{}}
mockMetricClient := &mocks.MetricsAPI{}
mockMetricClient.On("GetMetricDataWithContext", mock.Anything, mock.Anything, mock.Anything).Return(
&cloudwatch.GetMetricDataOutput{
MetricDataResults: []*cloudwatch.MetricDataResult{{Values: []*float64{}}},
}, nil).Once()
_, err := executor.executeRequest(contextWithFeaturesEnabled(features.FlagCloudWatchRoundUpEndTime), mockMetricClient, inputs)
require.NoError(t, err)
expectedTime, _ := time.Parse("2006-01-02T15:04:05Z07:00", "2024-05-01T01:46:00Z")
expectedInput := &cloudwatch.GetMetricDataInput{EndTime: &expectedTime, MetricDataQueries: []*cloudwatch.MetricDataQuery{}}
mockMetricClient.AssertCalled(t, "GetMetricDataWithContext", mock.Anything, expectedInput, mock.Anything)
})
}
func TestGetMetricDataExecutorTestResponse(t *testing.T) {
executor := &cloudWatchExecutor{}
inputs := &cloudwatch.GetMetricDataInput{MetricDataQueries: []*cloudwatch.MetricDataQuery{}}
inputs := &cloudwatch.GetMetricDataInput{EndTime: aws.Time(time.Now()), MetricDataQueries: []*cloudwatch.MetricDataQuery{}}
mockMetricClient := &mocks.MetricsAPI{}
mockMetricClient.On("GetMetricDataWithContext", mock.Anything, mock.Anything, mock.Anything).Return(
&cloudwatch.GetMetricDataOutput{