diff --git a/public/app/plugins/datasource/cloudwatch/datasource.js b/public/app/plugins/datasource/cloudwatch/datasource.js
index 2b152131bc2..f606b6e3dc8 100644
--- a/public/app/plugins/datasource/cloudwatch/datasource.js
+++ b/public/app/plugins/datasource/cloudwatch/datasource.js
@@ -231,33 +231,32 @@ function (angular, _, moment, dateMath) {
var region = templateSrv.replace(annotation.region);
var namespace = templateSrv.replace(annotation.namespace);
var metricName = templateSrv.replace(annotation.metricName);
- var dimensionPart = templateSrv.replace(annotation.dimensions);
- var statistic = templateSrv.replace(annotation.statistic) || '';
+ var dimensions = convertDimensionFormat(annotation.dimensions);
+ var statistics = _.map(annotation.statistics, function(s) { return templateSrv.replace(s); });
var period = annotation.period || '300';
-
- if (!region || !namespace || !metricName) { return $q.when([]); }
-
- var dimensions = {};
- if (!_.isEmpty(dimensionPart)) {
- _.each(dimensionPart.split(','), function(v) {
- var t = v.split('=');
- if (t.length !== 2) {
- throw new Error('Invalid query format');
- }
- dimensions[t[0]] = t[1];
- });
- dimensions = convertDimensionFormat(dimensions);
- }
period = parseInt(period, 10);
+ if (!region || !namespace || !metricName || _.isEmpty(statistics)) { return $q.when([]); }
+
var d = $q.defer();
var self = this;
- this.performDescribeAlarmsForMetric(region, namespace, metricName, dimensions, statistic, period).then(function(alarms) {
+ var allQueryPromise = _.map(statistics, function(statistic) {
+ return self.performDescribeAlarmsForMetric(region, namespace, metricName, dimensions, statistic, period);
+ });
+ $q.all(allQueryPromise).then(function(alarms) {
var eventList = [];
var start = convertToCloudWatchTime(options.range.from, false);
var end = convertToCloudWatchTime(options.range.to, true);
- _.each(alarms.MetricAlarms, function(alarm) {
+ _.chain(alarms)
+ .pluck('MetricAlarms')
+ .flatten()
+ .each(function(alarm) {
+ if (!alarm) {
+ d.resolve(eventList);
+ return;
+ }
+
self.performDescribeAlarmHistory(region, alarm.AlarmName, start, end).then(function(history) {
_.each(history.AlarmHistoryItems, function(h) {
var event = {
diff --git a/public/app/plugins/datasource/cloudwatch/directives.js b/public/app/plugins/datasource/cloudwatch/directives.js
index 22a98e036e4..a08d4fc8d9a 100644
--- a/public/app/plugins/datasource/cloudwatch/directives.js
+++ b/public/app/plugins/datasource/cloudwatch/directives.js
@@ -1,5 +1,6 @@
define([
'angular',
+ './query_parameter_ctrl',
],
function (angular) {
'use strict';
@@ -14,4 +15,17 @@ function (angular) {
return {templateUrl: 'app/plugins/datasource/cloudwatch/partials/annotations.editor.html'};
});
+ module.directive('cloudwatchQueryParameter', function() {
+ return {
+ templateUrl: 'app/plugins/datasource/cloudwatch/partials/query.parameter.html',
+ controller: 'CloudWatchQueryParameterCtrl',
+ restrict: 'E',
+ scope: {
+ target: "=",
+ datasourceName: "@",
+ onChange: "&",
+ }
+ };
+ });
+
});
diff --git a/public/app/plugins/datasource/cloudwatch/partials/annotations.editor.html b/public/app/plugins/datasource/cloudwatch/partials/annotations.editor.html
index ff545b7bf01..dfecb80032d 100644
--- a/public/app/plugins/datasource/cloudwatch/partials/annotations.editor.html
+++ b/public/app/plugins/datasource/cloudwatch/partials/annotations.editor.html
@@ -1,41 +1 @@
-
-
-
-
-
+
diff --git a/public/app/plugins/datasource/cloudwatch/partials/query.editor.html b/public/app/plugins/datasource/cloudwatch/partials/query.editor.html
index 0984bc521e2..cc2dfa3a601 100644
--- a/public/app/plugins/datasource/cloudwatch/partials/query.editor.html
+++ b/public/app/plugins/datasource/cloudwatch/partials/query.editor.html
@@ -33,61 +33,16 @@
-
-
-
-
-
-
-
+
diff --git a/public/app/plugins/datasource/cloudwatch/partials/query.parameter.html b/public/app/plugins/datasource/cloudwatch/partials/query.parameter.html
new file mode 100644
index 00000000000..6e2dde5bf48
--- /dev/null
+++ b/public/app/plugins/datasource/cloudwatch/partials/query.parameter.html
@@ -0,0 +1,53 @@
+
+
+
+
+
+
diff --git a/public/app/plugins/datasource/cloudwatch/query_ctrl.js b/public/app/plugins/datasource/cloudwatch/query_ctrl.js
index d0f6fe5b52a..e24b73cd068 100644
--- a/public/app/plugins/datasource/cloudwatch/query_ctrl.js
+++ b/public/app/plugins/datasource/cloudwatch/query_ctrl.js
@@ -7,173 +7,10 @@ function (angular, _) {
var module = angular.module('grafana.controllers');
- module.controller('CloudWatchQueryCtrl', function($scope, templateSrv, uiSegmentSrv, $q) {
+ module.controller('CloudWatchQueryCtrl', function($scope) {
$scope.init = function() {
- var target = $scope.target;
- target.namespace = target.namespace || '';
- target.metricName = target.metricName || '';
- target.statistics = target.statistics || ['Average'];
- target.dimensions = target.dimensions || {};
- target.period = target.period || '';
- target.region = target.region || $scope.datasource.getDefaultRegion();
-
$scope.aliasSyntax = '{{metric}} {{stat}} {{namespace}} {{region}} {{}}';
-
- $scope.regionSegment = uiSegmentSrv.getSegmentForValue($scope.target.region, 'select region');
- $scope.namespaceSegment = uiSegmentSrv.getSegmentForValue($scope.target.namespace, 'select namespace');
- $scope.metricSegment = uiSegmentSrv.getSegmentForValue($scope.target.metricName, 'select metric');
-
- $scope.dimSegments = _.reduce($scope.target.dimensions, function(memo, value, key) {
- memo.push(uiSegmentSrv.newKey(key));
- memo.push(uiSegmentSrv.newOperator("="));
- memo.push(uiSegmentSrv.newKeyValue(value));
- return memo;
- }, []);
-
- $scope.statSegments = _.map($scope.target.statistics, function(stat) {
- return uiSegmentSrv.getSegmentForValue(stat);
- });
-
- $scope.ensurePlusButton($scope.statSegments);
- $scope.ensurePlusButton($scope.dimSegments);
- $scope.removeDimSegment = uiSegmentSrv.newSegment({fake: true, value: '-- remove dimension --'});
- $scope.removeStatSegment = uiSegmentSrv.newSegment({fake: true, value: '-- remove stat --'});
- };
-
- $scope.getStatSegments = function() {
- return $q.when([
- angular.copy($scope.removeStatSegment),
- uiSegmentSrv.getSegmentForValue('Average'),
- uiSegmentSrv.getSegmentForValue('Maximum'),
- uiSegmentSrv.getSegmentForValue('Minimum'),
- uiSegmentSrv.getSegmentForValue('Sum'),
- uiSegmentSrv.getSegmentForValue('SampleCount'),
- ]);
- };
-
- $scope.statSegmentChanged = function(segment, index) {
- if (segment.value === $scope.removeStatSegment.value) {
- $scope.statSegments.splice(index, 1);
- } else {
- segment.type = 'value';
- }
-
- $scope.target.statistics = _.reduce($scope.statSegments, function(memo, seg) {
- if (!seg.fake) { memo.push(seg.value); } return memo;
- }, []);
-
- $scope.ensurePlusButton($scope.statSegments);
- $scope.get_data();
- };
-
- $scope.ensurePlusButton = function(segments) {
- var count = segments.length;
- var lastSegment = segments[Math.max(count-1, 0)];
-
- if (!lastSegment || lastSegment.type !== 'plus-button') {
- segments.push(uiSegmentSrv.newPlusButton());
- }
- };
-
- $scope.getDimSegments = function(segment, $index) {
- if (segment.type === 'operator') { return $q.when([]); }
-
- var target = $scope.target;
- var query = $q.when([]);
-
- if (segment.type === 'key' || segment.type === 'plus-button') {
- query = $scope.datasource.getDimensionKeys($scope.target.namespace);
- } else if (segment.type === 'value') {
- var dimensionKey = $scope.dimSegments[$index-2].value;
- query = $scope.datasource.getDimensionValues(target.region, target.namespace, target.metricName, dimensionKey, {});
- }
-
- return query.then($scope.transformToSegments(true)).then(function(results) {
- if (segment.type === 'key') {
- results.splice(0, 0, angular.copy($scope.removeDimSegment));
- }
- return results;
- });
- };
-
- $scope.dimSegmentChanged = function(segment, index) {
- $scope.dimSegments[index] = segment;
-
- if (segment.value === $scope.removeDimSegment.value) {
- $scope.dimSegments.splice(index, 3);
- }
- else if (segment.type === 'plus-button') {
- $scope.dimSegments.push(uiSegmentSrv.newOperator('='));
- $scope.dimSegments.push(uiSegmentSrv.newFake('select dimension value', 'value', 'query-segment-value'));
- segment.type = 'key';
- segment.cssClass = 'query-segment-key';
- }
-
- $scope.syncDimSegmentsWithModel();
- $scope.ensurePlusButton($scope.dimSegments);
- $scope.get_data();
- };
-
- $scope.syncDimSegmentsWithModel = function() {
- var dims = {};
- var length = $scope.dimSegments.length;
-
- for (var i = 0; i < length - 2; i += 3) {
- var keySegment = $scope.dimSegments[i];
- var valueSegment = $scope.dimSegments[i + 2];
- if (!valueSegment.fake) {
- dims[keySegment.value] = valueSegment.value;
- }
- }
-
- $scope.target.dimensions = dims;
- };
-
- $scope.getRegions = function() {
- return $scope.datasource.metricFindQuery('regions()')
- .then($scope.transformToSegments(true));
- };
-
- $scope.getNamespaces = function() {
- return $scope.datasource.metricFindQuery('namespaces()')
- .then($scope.transformToSegments(true));
- };
-
- $scope.getMetrics = function() {
- return $scope.datasource.metricFindQuery('metrics(' + $scope.target.namespace + ')')
- .then($scope.transformToSegments(true));
- };
-
- $scope.regionChanged = function() {
- $scope.target.region = $scope.regionSegment.value;
- $scope.get_data();
- };
-
- $scope.namespaceChanged = function() {
- $scope.target.namespace = $scope.namespaceSegment.value;
- $scope.get_data();
- };
-
- $scope.metricChanged = function() {
- $scope.target.metricName = $scope.metricSegment.value;
- $scope.get_data();
- };
-
- $scope.transformToSegments = function(addTemplateVars) {
- return function(results) {
- var segments = _.map(results, function(segment) {
- return uiSegmentSrv.newSegment({ value: segment.text, expandable: segment.expandable });
- });
-
- if (addTemplateVars) {
- _.each(templateSrv.variables, function(variable) {
- segments.unshift(uiSegmentSrv.newSegment({ type: 'template', value: '$' + variable.name, expandable: true }));
- });
- }
-
- return segments;
- };
};
$scope.refreshMetricData = function() {
diff --git a/public/app/plugins/datasource/cloudwatch/query_parameter_ctrl.js b/public/app/plugins/datasource/cloudwatch/query_parameter_ctrl.js
new file mode 100644
index 00000000000..0ed23aff205
--- /dev/null
+++ b/public/app/plugins/datasource/cloudwatch/query_parameter_ctrl.js
@@ -0,0 +1,192 @@
+define([
+ 'angular',
+ 'lodash',
+],
+function (angular, _) {
+ 'use strict';
+
+ var module = angular.module('grafana.controllers');
+
+ module.controller('CloudWatchQueryParameterCtrl', function($scope, templateSrv, uiSegmentSrv, datasourceSrv, $q) {
+
+ $scope.init = function() {
+ var target = $scope.target;
+ target.namespace = target.namespace || '';
+ target.metricName = target.metricName || '';
+ target.statistics = target.statistics || ['Average'];
+ target.dimensions = target.dimensions || {};
+ target.period = target.period || '';
+ target.region = target.region || '';
+
+ $scope.regionSegment = uiSegmentSrv.getSegmentForValue($scope.target.region, 'select region');
+ $scope.namespaceSegment = uiSegmentSrv.getSegmentForValue($scope.target.namespace, 'select namespace');
+ $scope.metricSegment = uiSegmentSrv.getSegmentForValue($scope.target.metricName, 'select metric');
+
+ $scope.dimSegments = _.reduce($scope.target.dimensions, function(memo, value, key) {
+ memo.push(uiSegmentSrv.newKey(key));
+ memo.push(uiSegmentSrv.newOperator("="));
+ memo.push(uiSegmentSrv.newKeyValue(value));
+ return memo;
+ }, []);
+
+ $scope.statSegments = _.map($scope.target.statistics, function(stat) {
+ return uiSegmentSrv.getSegmentForValue(stat);
+ });
+
+ $scope.ensurePlusButton($scope.statSegments);
+ $scope.ensurePlusButton($scope.dimSegments);
+ $scope.removeDimSegment = uiSegmentSrv.newSegment({fake: true, value: '-- remove dimension --'});
+ $scope.removeStatSegment = uiSegmentSrv.newSegment({fake: true, value: '-- remove stat --'});
+
+ datasourceSrv.get($scope.datasourceName).then(function(datasource) {
+ $scope.datasource = datasource;
+ if (_.isEmpty($scope.target.region)) {
+ $scope.target.region = $scope.datasource.getDefaultRegion();
+ }
+ });
+
+ if (!$scope.onChange) {
+ $scope.onChange = function() {};
+ }
+ };
+
+ $scope.getStatSegments = function() {
+ return $q.when([
+ angular.copy($scope.removeStatSegment),
+ uiSegmentSrv.getSegmentForValue('Average'),
+ uiSegmentSrv.getSegmentForValue('Maximum'),
+ uiSegmentSrv.getSegmentForValue('Minimum'),
+ uiSegmentSrv.getSegmentForValue('Sum'),
+ uiSegmentSrv.getSegmentForValue('SampleCount'),
+ ]);
+ };
+
+ $scope.statSegmentChanged = function(segment, index) {
+ if (segment.value === $scope.removeStatSegment.value) {
+ $scope.statSegments.splice(index, 1);
+ } else {
+ segment.type = 'value';
+ }
+
+ $scope.target.statistics = _.reduce($scope.statSegments, function(memo, seg) {
+ if (!seg.fake) { memo.push(seg.value); } return memo;
+ }, []);
+
+ $scope.ensurePlusButton($scope.statSegments);
+ $scope.onChange();
+ };
+
+ $scope.ensurePlusButton = function(segments) {
+ var count = segments.length;
+ var lastSegment = segments[Math.max(count-1, 0)];
+
+ if (!lastSegment || lastSegment.type !== 'plus-button') {
+ segments.push(uiSegmentSrv.newPlusButton());
+ }
+ };
+
+ $scope.getDimSegments = function(segment, $index) {
+ if (segment.type === 'operator') { return $q.when([]); }
+
+ var target = $scope.target;
+ var query = $q.when([]);
+
+ if (segment.type === 'key' || segment.type === 'plus-button') {
+ query = $scope.datasource.getDimensionKeys($scope.target.namespace);
+ } else if (segment.type === 'value') {
+ var dimensionKey = $scope.dimSegments[$index-2].value;
+ query = $scope.datasource.getDimensionValues(target.region, target.namespace, target.metricName, dimensionKey, {});
+ }
+
+ return query.then($scope.transformToSegments(true)).then(function(results) {
+ if (segment.type === 'key') {
+ results.splice(0, 0, angular.copy($scope.removeDimSegment));
+ }
+ return results;
+ });
+ };
+
+ $scope.dimSegmentChanged = function(segment, index) {
+ $scope.dimSegments[index] = segment;
+
+ if (segment.value === $scope.removeDimSegment.value) {
+ $scope.dimSegments.splice(index, 3);
+ }
+ else if (segment.type === 'plus-button') {
+ $scope.dimSegments.push(uiSegmentSrv.newOperator('='));
+ $scope.dimSegments.push(uiSegmentSrv.newFake('select dimension value', 'value', 'query-segment-value'));
+ segment.type = 'key';
+ segment.cssClass = 'query-segment-key';
+ }
+
+ $scope.syncDimSegmentsWithModel();
+ $scope.ensurePlusButton($scope.dimSegments);
+ $scope.onChange();
+ };
+
+ $scope.syncDimSegmentsWithModel = function() {
+ var dims = {};
+ var length = $scope.dimSegments.length;
+
+ for (var i = 0; i < length - 2; i += 3) {
+ var keySegment = $scope.dimSegments[i];
+ var valueSegment = $scope.dimSegments[i + 2];
+ if (!valueSegment.fake) {
+ dims[keySegment.value] = valueSegment.value;
+ }
+ }
+
+ $scope.target.dimensions = dims;
+ };
+
+ $scope.getRegions = function() {
+ return $scope.datasource.metricFindQuery('regions()')
+ .then($scope.transformToSegments(true));
+ };
+
+ $scope.getNamespaces = function() {
+ return $scope.datasource.metricFindQuery('namespaces()')
+ .then($scope.transformToSegments(true));
+ };
+
+ $scope.getMetrics = function() {
+ return $scope.datasource.metricFindQuery('metrics(' + $scope.target.namespace + ')')
+ .then($scope.transformToSegments(true));
+ };
+
+ $scope.regionChanged = function() {
+ $scope.target.region = $scope.regionSegment.value;
+ $scope.onChange();
+ };
+
+ $scope.namespaceChanged = function() {
+ $scope.target.namespace = $scope.namespaceSegment.value;
+ $scope.onChange();
+ };
+
+ $scope.metricChanged = function() {
+ $scope.target.metricName = $scope.metricSegment.value;
+ $scope.onChange();
+ };
+
+ $scope.transformToSegments = function(addTemplateVars) {
+ return function(results) {
+ var segments = _.map(results, function(segment) {
+ return uiSegmentSrv.newSegment({ value: segment.text, expandable: segment.expandable });
+ });
+
+ if (addTemplateVars) {
+ _.each(templateSrv.variables, function(variable) {
+ segments.unshift(uiSegmentSrv.newSegment({ type: 'template', value: '$' + variable.name, expandable: true }));
+ });
+ }
+
+ return segments;
+ };
+ };
+
+ $scope.init();
+
+ });
+
+});