diff --git a/pkg/tsdb/cloudwatch/cloudwatch.go b/pkg/tsdb/cloudwatch/cloudwatch.go index d5bdd010269..3879dce4ea6 100644 --- a/pkg/tsdb/cloudwatch/cloudwatch.go +++ b/pkg/tsdb/cloudwatch/cloudwatch.go @@ -152,8 +152,6 @@ func (e *CloudWatchExecutor) executeQuery(ctx context.Context, parameters *simpl MetricName: aws.String(query.MetricName), Dimensions: query.Dimensions, Period: aws.Int64(int64(query.Period)), - StartTime: aws.Time(startTime), - EndTime: aws.Time(endTime), } if len(query.Statistics) > 0 { params.Statistics = query.Statistics @@ -162,15 +160,36 @@ func (e *CloudWatchExecutor) executeQuery(ctx context.Context, parameters *simpl params.ExtendedStatistics = query.ExtendedStatistics } - if setting.Env == setting.DEV { - plog.Debug("CloudWatch query", "raw query", params) + // 1 minutes resolutin metrics is stored for 15 days, 15 * 24 * 60 = 21600 + if query.HighResolution && (((endTime.Unix() - startTime.Unix()) / int64(query.Period)) > 21600) { + return nil, errors.New("too long query period") } + var resp *cloudwatch.GetMetricStatisticsOutput + for startTime.Before(endTime) { + params.StartTime = aws.Time(startTime) + if query.HighResolution { + startTime = startTime.Add(time.Duration(1440*query.Period) * time.Second) + } else { + startTime = endTime + } + params.EndTime = aws.Time(startTime) - resp, err := client.GetMetricStatisticsWithContext(ctx, params, request.WithResponseReadTimeout(10*time.Second)) - if err != nil { - return nil, err + if setting.Env == setting.DEV { + plog.Debug("CloudWatch query", "raw query", params) + } + + partResp, err := client.GetMetricStatisticsWithContext(ctx, params, request.WithResponseReadTimeout(10*time.Second)) + if err != nil { + return nil, err + } + if resp != nil { + resp.Datapoints = append(resp.Datapoints, partResp.Datapoints...) + } else { + resp = partResp + + } + metrics.M_Aws_CloudWatch_GetMetricStatistics.Inc() } - metrics.M_Aws_CloudWatch_GetMetricStatistics.Inc() queryRes, err := parseResponse(resp, query) if err != nil { @@ -274,6 +293,8 @@ func parseQuery(model *simplejson.Json) (*CloudWatchQuery, error) { alias = "{{metric}}_{{stat}}" } + highResolution := model.Get("highResolution").MustBool(false) + return &CloudWatchQuery{ Region: region, Namespace: namespace, @@ -283,6 +304,7 @@ func parseQuery(model *simplejson.Json) (*CloudWatchQuery, error) { ExtendedStatistics: aws.StringSlice(extendedStatistics), Period: period, Alias: alias, + HighResolution: highResolution, }, nil } diff --git a/pkg/tsdb/cloudwatch/cloudwatch_test.go b/pkg/tsdb/cloudwatch/cloudwatch_test.go index 5c322a44d56..719edba08ba 100644 --- a/pkg/tsdb/cloudwatch/cloudwatch_test.go +++ b/pkg/tsdb/cloudwatch/cloudwatch_test.go @@ -31,6 +31,7 @@ func TestCloudWatch(t *testing.T) { "p90.00" ], "period": "60", + "highResolution": false, "alias": "{{metric}}_{{stat}}" } ` diff --git a/pkg/tsdb/cloudwatch/types.go b/pkg/tsdb/cloudwatch/types.go index c2a5ab8c3d7..0737b64686d 100644 --- a/pkg/tsdb/cloudwatch/types.go +++ b/pkg/tsdb/cloudwatch/types.go @@ -13,4 +13,5 @@ type CloudWatchQuery struct { ExtendedStatistics []*string Period int Alias string + HighResolution bool } diff --git a/public/app/plugins/datasource/cloudwatch/datasource.ts b/public/app/plugins/datasource/cloudwatch/datasource.ts index facddd2e18e..09bf53d05cf 100644 --- a/public/app/plugins/datasource/cloudwatch/datasource.ts +++ b/public/app/plugins/datasource/cloudwatch/datasource.ts @@ -106,7 +106,7 @@ export default class CloudWatchDatasource { if (period < 1) { period = 1; } - if (range / period >= 1440) { + if (!target.highResolution && range / period >= 1440) { period = Math.ceil(range / 1440 / periodUnit) * periodUnit; } diff --git a/public/app/plugins/datasource/cloudwatch/partials/query.parameter.html b/public/app/plugins/datasource/cloudwatch/partials/query.parameter.html index 9da0e2d71c4..81bad39e23a 100644 --- a/public/app/plugins/datasource/cloudwatch/partials/query.parameter.html +++ b/public/app/plugins/datasource/cloudwatch/partials/query.parameter.html @@ -54,6 +54,11 @@ +
+ + +
+
diff --git a/public/app/plugins/datasource/cloudwatch/query_parameter_ctrl.ts b/public/app/plugins/datasource/cloudwatch/query_parameter_ctrl.ts index f344162db70..0b47ebd7069 100644 --- a/public/app/plugins/datasource/cloudwatch/query_parameter_ctrl.ts +++ b/public/app/plugins/datasource/cloudwatch/query_parameter_ctrl.ts @@ -27,6 +27,7 @@ export class CloudWatchQueryParameterCtrl { target.dimensions = target.dimensions || {}; target.period = target.period || ''; target.region = target.region || 'default'; + target.highResolution = target.highResolution || false; $scope.regionSegment = uiSegmentSrv.getSegmentForValue($scope.target.region, 'select region'); $scope.namespaceSegment = uiSegmentSrv.getSegmentForValue($scope.target.namespace, 'select namespace');