Skip to content

Commit 9bb440b

Browse files
committed
Merge branch 'master' of github.com:grafana/grafana
2 parents 62269bb + e73b82d commit 9bb440b

File tree

7 files changed

+151
-35
lines changed

7 files changed

+151
-35
lines changed

pkg/api/cloudwatch/cloudwatch.go

Lines changed: 31 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -181,25 +181,33 @@ func handleGetMetricStatistics(req *cwRequest, c *middleware.Context) {
181181

182182
reqParam := &struct {
183183
Parameters struct {
184-
Namespace string `json:"namespace"`
185-
MetricName string `json:"metricName"`
186-
Dimensions []*cloudwatch.Dimension `json:"dimensions"`
187-
Statistics []*string `json:"statistics"`
188-
StartTime int64 `json:"startTime"`
189-
EndTime int64 `json:"endTime"`
190-
Period int64 `json:"period"`
184+
Namespace string `json:"namespace"`
185+
MetricName string `json:"metricName"`
186+
Dimensions []*cloudwatch.Dimension `json:"dimensions"`
187+
Statistics []*string `json:"statistics"`
188+
ExtendedStatistics []*string `json:"extendedStatistics"`
189+
StartTime int64 `json:"startTime"`
190+
EndTime int64 `json:"endTime"`
191+
Period int64 `json:"period"`
191192
} `json:"parameters"`
192193
}{}
193194
json.Unmarshal(req.Body, reqParam)
194195

195196
params := &cloudwatch.GetMetricStatisticsInput{
196-
Namespace: aws.String(reqParam.Parameters.Namespace),
197-
MetricName: aws.String(reqParam.Parameters.MetricName),
198-
Dimensions: reqParam.Parameters.Dimensions,
199-
Statistics: reqParam.Parameters.Statistics,
200-
StartTime: aws.Time(time.Unix(reqParam.Parameters.StartTime, 0)),
201-
EndTime: aws.Time(time.Unix(reqParam.Parameters.EndTime, 0)),
202-
Period: aws.Int64(reqParam.Parameters.Period),
197+
Namespace: aws.String(reqParam.Parameters.Namespace),
198+
MetricName: aws.String(reqParam.Parameters.MetricName),
199+
Dimensions: reqParam.Parameters.Dimensions,
200+
Statistics: reqParam.Parameters.Statistics,
201+
ExtendedStatistics: reqParam.Parameters.ExtendedStatistics,
202+
StartTime: aws.Time(time.Unix(reqParam.Parameters.StartTime, 0)),
203+
EndTime: aws.Time(time.Unix(reqParam.Parameters.EndTime, 0)),
204+
Period: aws.Int64(reqParam.Parameters.Period),
205+
}
206+
if len(reqParam.Parameters.Statistics) != 0 {
207+
params.Statistics = reqParam.Parameters.Statistics
208+
}
209+
if len(reqParam.Parameters.ExtendedStatistics) != 0 {
210+
params.ExtendedStatistics = reqParam.Parameters.ExtendedStatistics
203211
}
204212

205213
resp, err := svc.GetMetricStatistics(params)
@@ -292,11 +300,12 @@ func handleDescribeAlarmsForMetric(req *cwRequest, c *middleware.Context) {
292300

293301
reqParam := &struct {
294302
Parameters struct {
295-
Namespace string `json:"namespace"`
296-
MetricName string `json:"metricName"`
297-
Dimensions []*cloudwatch.Dimension `json:"dimensions"`
298-
Statistic string `json:"statistic"`
299-
Period int64 `json:"period"`
303+
Namespace string `json:"namespace"`
304+
MetricName string `json:"metricName"`
305+
Dimensions []*cloudwatch.Dimension `json:"dimensions"`
306+
Statistic string `json:"statistic"`
307+
ExtendedStatistic string `json:"extendedStatistic"`
308+
Period int64 `json:"period"`
300309
} `json:"parameters"`
301310
}{}
302311
json.Unmarshal(req.Body, reqParam)
@@ -312,6 +321,9 @@ func handleDescribeAlarmsForMetric(req *cwRequest, c *middleware.Context) {
312321
if reqParam.Parameters.Statistic != "" {
313322
params.Statistic = aws.String(reqParam.Parameters.Statistic)
314323
}
324+
if reqParam.Parameters.ExtendedStatistic != "" {
325+
params.ExtendedStatistic = aws.String(reqParam.Parameters.ExtendedStatistic)
326+
}
315327

316328
resp, err := svc.DescribeAlarmsForMetric(params)
317329
if err != nil {

pkg/components/renderer/renderer.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@ func RenderToPng(params *RenderOpts) (string, error) {
5252

5353
cmdArgs := []string{
5454
"--ignore-ssl-errors=true",
55+
"--web-security=false",
5556
scriptPath,
5657
"url=" + url,
5758
"width=" + params.Width,

public/app/features/templating/templateSrv.js

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -112,10 +112,18 @@ function (angular, _, kbn) {
112112
this._grafanaVariables[name] = value;
113113
};
114114

115-
this.variableExists = function(expression) {
115+
this.getVariableName = function(expression) {
116116
this._regex.lastIndex = 0;
117117
var match = this._regex.exec(expression);
118-
return match && (self._index[match[1] || match[2]] !== void 0);
118+
if (!match) {
119+
return null;
120+
}
121+
return match[1] || match[2];
122+
};
123+
124+
this.variableExists = function(expression) {
125+
var name = this.getVariableName(expression);
126+
return name && (self._index[name] !== void 0);
119127
};
120128

121129
this.highlightVariablesAsHtml = function(str) {

public/app/plugins/datasource/cloudwatch/datasource.js

Lines changed: 30 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,13 @@ function (angular, _, moment, dateMath, kbn, CloudWatchAnnotationQuery) {
1616
this.supportMetrics = true;
1717
this.proxyUrl = instanceSettings.url;
1818
this.defaultRegion = instanceSettings.jsonData.defaultRegion;
19+
this.standardStatistics = [
20+
'Average',
21+
'Maximum',
22+
'Minimum',
23+
'Sum',
24+
'SampleCount'
25+
];
1926

2027
var self = this;
2128
this.query = function(options) {
@@ -24,7 +31,7 @@ function (angular, _, moment, dateMath, kbn, CloudWatchAnnotationQuery) {
2431

2532
var queries = [];
2633
options = angular.copy(options);
27-
options.targets = this.expandTemplateVariable(options.targets, templateSrv);
34+
options.targets = this.expandTemplateVariable(options.targets, options.scopedVars, templateSrv);
2835
_.each(options.targets, function(target) {
2936
if (target.hide || !target.namespace || !target.metricName || _.isEmpty(target.statistics)) {
3037
return;
@@ -98,14 +105,17 @@ function (angular, _, moment, dateMath, kbn, CloudWatchAnnotationQuery) {
98105
};
99106

100107
this.performTimeSeriesQuery = function(query, start, end) {
108+
var statistics = _.filter(query.statistics, function(s) { return _.includes(self.standardStatistics, s); });
109+
var extendedStatistics = _.reject(query.statistics, function(s) { return _.includes(self.standardStatistics, s); });
101110
return this.awsRequest({
102111
region: query.region,
103112
action: 'GetMetricStatistics',
104113
parameters: {
105114
namespace: query.namespace,
106115
metricName: query.metricName,
107116
dimensions: query.dimensions,
108-
statistics: query.statistics,
117+
statistics: statistics,
118+
extendedStatistics: extendedStatistics,
109119
startTime: start,
110120
endTime: end,
111121
period: query.period
@@ -268,10 +278,19 @@ function (angular, _, moment, dateMath, kbn, CloudWatchAnnotationQuery) {
268278
};
269279

270280
this.performDescribeAlarmsForMetric = function(region, namespace, metricName, dimensions, statistic, period) {
281+
var s = _.includes(self.standardStatistics, statistic) ? statistic : '';
282+
var es = _.includes(self.standardStatistics, statistic) ? '' : statistic;
271283
return this.awsRequest({
272284
region: region,
273285
action: 'DescribeAlarmsForMetric',
274-
parameters: { namespace: namespace, metricName: metricName, dimensions: dimensions, statistic: statistic, period: period }
286+
parameters: {
287+
namespace: namespace,
288+
metricName: metricName,
289+
dimensions: dimensions,
290+
statistic: s,
291+
extendedStatistic: es,
292+
period: period
293+
}
275294
});
276295
};
277296

@@ -338,6 +357,7 @@ function (angular, _, moment, dateMath, kbn, CloudWatchAnnotationQuery) {
338357
var periodMs = options.period * 1000;
339358

340359
return _.map(options.statistics, function(stat) {
360+
var extended = !_.includes(self.standardStatistics, stat);
341361
var dps = [];
342362
var lastTimestamp = null;
343363
_.chain(md.Datapoints)
@@ -350,7 +370,11 @@ function (angular, _, moment, dateMath, kbn, CloudWatchAnnotationQuery) {
350370
dps.push([null, lastTimestamp + periodMs]);
351371
}
352372
lastTimestamp = timestamp;
353-
dps.push([dp[stat], timestamp]);
373+
if (!extended) {
374+
dps.push([dp[stat], timestamp]);
375+
} else {
376+
dps.push([dp.ExtendedStatistics[stat], timestamp]);
377+
}
354378
})
355379
.value();
356380

@@ -388,12 +412,12 @@ function (angular, _, moment, dateMath, kbn, CloudWatchAnnotationQuery) {
388412
return str.indexOf('$' + variableName) !== -1;
389413
};
390414

391-
this.expandTemplateVariable = function(targets, templateSrv) {
415+
this.expandTemplateVariable = function(targets, scopedVars, templateSrv) {
392416
var self = this;
393417
return _.chain(targets)
394418
.map(function(target) {
395419
var dimensionKey = _.findKey(target.dimensions, function(v) {
396-
return templateSrv.variableExists(v);
420+
return templateSrv.variableExists(v) && !_.has(scopedVars, templateSrv.getVariableName(v));
397421
});
398422

399423
if (dimensionKey) {

public/app/plugins/datasource/cloudwatch/query_parameter_ctrl.js

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -61,14 +61,13 @@ function (angular, _) {
6161
};
6262

6363
$scope.getStatSegments = function() {
64-
return $q.when([
64+
return $q.when(_.flatten([
6565
angular.copy($scope.removeStatSegment),
66-
uiSegmentSrv.getSegmentForValue('Average'),
67-
uiSegmentSrv.getSegmentForValue('Maximum'),
68-
uiSegmentSrv.getSegmentForValue('Minimum'),
69-
uiSegmentSrv.getSegmentForValue('Sum'),
70-
uiSegmentSrv.getSegmentForValue('SampleCount'),
71-
]);
66+
_.map($scope.datasource.standardStatistics, function(s) {
67+
return uiSegmentSrv.getSegmentForValue(s);
68+
}),
69+
uiSegmentSrv.getSegmentForValue('pNN.NN'),
70+
]));
7271
};
7372

7473
$scope.statSegmentChanged = function(segment, index) {

public/app/plugins/datasource/cloudwatch/specs/datasource_specs.ts

Lines changed: 63 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,7 @@ describe('CloudWatchDatasource', function() {
139139
]
140140
}
141141
],
142+
getVariableName: function (e) { return 'instance_id'; },
142143
variableExists: function (e) { return true; },
143144
containsVariable: function (str, variableName) { return str.indexOf('$' + variableName) !== -1; }
144145
};
@@ -156,11 +157,72 @@ describe('CloudWatchDatasource', function() {
156157
}
157158
];
158159

159-
var result = ctx.ds.expandTemplateVariable(targets, templateSrv);
160+
var result = ctx.ds.expandTemplateVariable(targets, {}, templateSrv);
160161
expect(result[0].dimensions.InstanceId).to.be('i-34567890');
161162
});
162163
});
163164

165+
describe('When performing CloudWatch query for extended statistics', function() {
166+
var requestParams;
167+
168+
var query = {
169+
range: { from: 'now-1h', to: 'now' },
170+
targets: [
171+
{
172+
region: 'us-east-1',
173+
namespace: 'AWS/ApplicationELB',
174+
metricName: 'TargetResponseTime',
175+
dimensions: {
176+
LoadBalancer: 'lb',
177+
TargetGroup: 'tg'
178+
},
179+
statistics: ['p90.00'],
180+
period: 300
181+
}
182+
]
183+
};
184+
185+
var response = {
186+
Datapoints: [
187+
{
188+
ExtendedStatistics: {
189+
'p90.00': 1
190+
},
191+
Timestamp: 'Wed Dec 31 1969 16:00:00 GMT-0800 (PST)'
192+
},
193+
{
194+
ExtendedStatistics: {
195+
'p90.00': 2
196+
},
197+
Timestamp: 'Wed Dec 31 1969 16:05:00 GMT-0800 (PST)'
198+
},
199+
{
200+
ExtendedStatistics: {
201+
'p90.00': 5
202+
},
203+
Timestamp: 'Wed Dec 31 1969 16:15:00 GMT-0800 (PST)'
204+
}
205+
],
206+
Label: 'TargetResponseTime'
207+
};
208+
209+
beforeEach(function() {
210+
ctx.backendSrv.datasourceRequest = function(params) {
211+
requestParams = params;
212+
return ctx.$q.when({data: response});
213+
};
214+
});
215+
216+
it('should return series list', function(done) {
217+
ctx.ds.query(query).then(function(result) {
218+
expect(result.data[0].target).to.be('TargetResponseTime_p90.00');
219+
expect(result.data[0].datapoints[0][0]).to.be(response.Datapoints[0].ExtendedStatistics['p90.00']);
220+
done();
221+
});
222+
ctx.$rootScope.$apply();
223+
});
224+
});
225+
164226
function describeMetricFindQuery(query, func) {
165227
describe('metricFindQuery ' + query, () => {
166228
let scenario: any = {};

public/app/plugins/panel/graph/graph.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -185,13 +185,23 @@ module.directive('grafanaGraph', function($rootScope, timeSrv) {
185185

186186
// Series could have different timeSteps,
187187
// let's find the smallest one so that bars are correctly rendered.
188+
// In addition, only take series which are rendered as bars for this.
188189
function getMinTimeStepOfSeries(data) {
189190
var min = Number.MAX_VALUE;
190191

191192
for (let i = 0; i < data.length; i++) {
192193
if (!data[i].stats.timeStep) {
193194
continue;
194195
}
196+
if (panel.bars) {
197+
if (data[i].bars && data[i].bars.show === false) {
198+
continue;
199+
}
200+
} else {
201+
if (typeof data[i].bars === 'undefined' || typeof data[i].bars.show === 'undefined' || !data[i].bars.show) {
202+
continue;
203+
}
204+
}
195205

196206
if (data[i].stats.timeStep < min) {
197207
min = data[i].stats.timeStep;

0 commit comments

Comments
 (0)