Commit a589f701 by Carl Bergquist Committed by GitHub

Merge pull request #10925 from mtanda/cw_high_resolution

(cloudwatch) support high resolution query
parents 5153d8e5 eecbdc89
...@@ -152,8 +152,6 @@ func (e *CloudWatchExecutor) executeQuery(ctx context.Context, parameters *simpl ...@@ -152,8 +152,6 @@ func (e *CloudWatchExecutor) executeQuery(ctx context.Context, parameters *simpl
MetricName: aws.String(query.MetricName), MetricName: aws.String(query.MetricName),
Dimensions: query.Dimensions, Dimensions: query.Dimensions,
Period: aws.Int64(int64(query.Period)), Period: aws.Int64(int64(query.Period)),
StartTime: aws.Time(startTime),
EndTime: aws.Time(endTime),
} }
if len(query.Statistics) > 0 { if len(query.Statistics) > 0 {
params.Statistics = query.Statistics params.Statistics = query.Statistics
...@@ -162,15 +160,36 @@ func (e *CloudWatchExecutor) executeQuery(ctx context.Context, parameters *simpl ...@@ -162,15 +160,36 @@ func (e *CloudWatchExecutor) executeQuery(ctx context.Context, parameters *simpl
params.ExtendedStatistics = query.ExtendedStatistics params.ExtendedStatistics = query.ExtendedStatistics
} }
// 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)
if setting.Env == setting.DEV { if setting.Env == setting.DEV {
plog.Debug("CloudWatch query", "raw query", params) plog.Debug("CloudWatch query", "raw query", params)
} }
resp, err := client.GetMetricStatisticsWithContext(ctx, params, request.WithResponseReadTimeout(10*time.Second)) partResp, err := client.GetMetricStatisticsWithContext(ctx, params, request.WithResponseReadTimeout(10*time.Second))
if err != nil { if err != nil {
return nil, err 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) queryRes, err := parseResponse(resp, query)
if err != nil { if err != nil {
...@@ -274,6 +293,8 @@ func parseQuery(model *simplejson.Json) (*CloudWatchQuery, error) { ...@@ -274,6 +293,8 @@ func parseQuery(model *simplejson.Json) (*CloudWatchQuery, error) {
alias = "{{metric}}_{{stat}}" alias = "{{metric}}_{{stat}}"
} }
highResolution := model.Get("highResolution").MustBool(false)
return &CloudWatchQuery{ return &CloudWatchQuery{
Region: region, Region: region,
Namespace: namespace, Namespace: namespace,
...@@ -283,6 +304,7 @@ func parseQuery(model *simplejson.Json) (*CloudWatchQuery, error) { ...@@ -283,6 +304,7 @@ func parseQuery(model *simplejson.Json) (*CloudWatchQuery, error) {
ExtendedStatistics: aws.StringSlice(extendedStatistics), ExtendedStatistics: aws.StringSlice(extendedStatistics),
Period: period, Period: period,
Alias: alias, Alias: alias,
HighResolution: highResolution,
}, nil }, nil
} }
......
...@@ -31,6 +31,7 @@ func TestCloudWatch(t *testing.T) { ...@@ -31,6 +31,7 @@ func TestCloudWatch(t *testing.T) {
"p90.00" "p90.00"
], ],
"period": "60", "period": "60",
"highResolution": false,
"alias": "{{metric}}_{{stat}}" "alias": "{{metric}}_{{stat}}"
} }
` `
......
...@@ -13,4 +13,5 @@ type CloudWatchQuery struct { ...@@ -13,4 +13,5 @@ type CloudWatchQuery struct {
ExtendedStatistics []*string ExtendedStatistics []*string
Period int Period int
Alias string Alias string
HighResolution bool
} }
...@@ -106,7 +106,7 @@ export default class CloudWatchDatasource { ...@@ -106,7 +106,7 @@ export default class CloudWatchDatasource {
if (period < 1) { if (period < 1) {
period = 1; period = 1;
} }
if (range / period >= 1440) { if (!target.highResolution && range / period >= 1440) {
period = Math.ceil(range / 1440 / periodUnit) * periodUnit; period = Math.ceil(range / 1440 / periodUnit) * periodUnit;
} }
......
...@@ -54,6 +54,11 @@ ...@@ -54,6 +54,11 @@
</ul> </ul>
</info-popover> </info-popover>
</div> </div>
<div class="gf-form">
<gf-form-switch class="gf-form" label="HighRes" label-class="width-5" checked="target.highResolution" on-change="onChange()">
</gf-form-switch>
</div>
<div class="gf-form gf-form--grow"> <div class="gf-form gf-form--grow">
<div class="gf-form-label gf-form-label--grow"></div> <div class="gf-form-label gf-form-label--grow"></div>
</div> </div>
......
...@@ -27,6 +27,7 @@ export class CloudWatchQueryParameterCtrl { ...@@ -27,6 +27,7 @@ export class CloudWatchQueryParameterCtrl {
target.dimensions = target.dimensions || {}; target.dimensions = target.dimensions || {};
target.period = target.period || ''; target.period = target.period || '';
target.region = target.region || 'default'; target.region = target.region || 'default';
target.highResolution = target.highResolution || false;
$scope.regionSegment = uiSegmentSrv.getSegmentForValue($scope.target.region, 'select region'); $scope.regionSegment = uiSegmentSrv.getSegmentForValue($scope.target.region, 'select region');
$scope.namespaceSegment = uiSegmentSrv.getSegmentForValue($scope.target.namespace, 'select namespace'); $scope.namespaceSegment = uiSegmentSrv.getSegmentForValue($scope.target.namespace, 'select namespace');
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment