diff --git a/public/app/plugins/datasource/cloudwatch/datasource.js b/public/app/plugins/datasource/cloudwatch/datasource.js index aa767b6c25c..12cc611ba7e 100644 --- a/public/app/plugins/datasource/cloudwatch/datasource.js +++ b/public/app/plugins/datasource/cloudwatch/datasource.js @@ -124,11 +124,12 @@ function (angular, _) { }; return this.awsRequest(request).then(function(result) { - console.log(result); return _.chain(result.Metrics).map(function(metric) { return _.pluck(metric.Dimensions, 'Value'); }).flatten().uniq().sortBy(function(name) { return name; + }).map(function(value) { + return {value: value, text: value}; }).value(); }); }; @@ -137,10 +138,7 @@ function (angular, _) { return this.awsRequest({ region: region, action: 'DescribeInstances', - parameters: { - filter: filters, - instanceIds: instanceIds - } + parameters: { filter: filters, instanceIds: instanceIds } }); }; @@ -247,6 +245,7 @@ function (angular, _) { function transformMetricData(md, options) { var result = []; + console.log(options); var dimensionPart = templateSrv.replace(JSON.stringify(options.dimensions)); _.each(getActivatedStatistics(options.statistics), function(s) { var originalSettings = _.templateSettings; diff --git a/public/app/plugins/datasource/cloudwatch/partials/query.editor.html b/public/app/plugins/datasource/cloudwatch/partials/query.editor.html index 47db2821158..674ab2e4462 100644 --- a/public/app/plugins/datasource/cloudwatch/partials/query.editor.html +++ b/public/app/plugins/datasource/cloudwatch/partials/query.editor.html @@ -55,40 +55,10 @@
  • Dimensions
  • -
  • - {{key}} = {{value}} - - - -
  • - -
  • - - - -
  • - -
  • - - - - add dimension - +
  • +
  • -
    diff --git a/public/app/plugins/datasource/cloudwatch/query_ctrl.js b/public/app/plugins/datasource/cloudwatch/query_ctrl.js index 7f095db58f3..5a1a34e7d5b 100644 --- a/public/app/plugins/datasource/cloudwatch/query_ctrl.js +++ b/public/app/plugins/datasource/cloudwatch/query_ctrl.js @@ -7,36 +7,106 @@ function (angular, _) { var module = angular.module('grafana.controllers'); - module.controller('CloudWatchQueryCtrl', function($scope, templateSrv, uiSegmentSrv) { + module.controller('CloudWatchQueryCtrl', function($scope, templateSrv, uiSegmentSrv, $q) { $scope.init = function() { $scope.target.namespace = $scope.target.namespace || ''; $scope.target.metricName = $scope.target.metricName || ''; + $scope.target.statistics = $scope.target.statistics || {Average: true}; $scope.target.dimensions = $scope.target.dimensions || {}; - $scope.target.escapedDimensions = this.escapeDimensions($scope.target.dimensions); - $scope.target.statistics = $scope.target.statistics || {}; $scope.target.period = $scope.target.period || 60; $scope.target.region = $scope.target.region || $scope.datasource.getDefaultRegion(); - $scope.target.errors = validateTarget(); $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.fixSegments(); + $scope.removeDimSegment = uiSegmentSrv.newSegment({fake: true, value: '-- remove dimension --'}); + }; + + $scope.fixSegments = function() { + var count = $scope.dimSegments.length; + var lastSegment = $scope.dimSegments[Math.max(count-1, 0)]; + + if (!lastSegment || lastSegment.type !== 'plus-button') { + $scope.dimSegments.push(uiSegmentSrv.newPlusButton()); + } + }; + + $scope.getDimSegments = function(segment) { + 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') { + query = $scope.datasource.getDimensionValues(target.region, target.namespace, target.metricName, {}); + } + + 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.fixSegments(); + $scope.syncDimSegmentsWithModel(); + $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)); + .then($scope.transformToSegments(true)); }; $scope.getNamespaces = function() { return $scope.datasource.metricFindQuery('namespaces()') - .then($scope.transformToSegments(true)); + .then($scope.transformToSegments(true)); }; $scope.getMetrics = function() { return $scope.datasource.metricFindQuery('metrics(' + $scope.target.namespace + ')') - .then($scope.transformToSegments(true)); + .then($scope.transformToSegments(true)); }; $scope.regionChanged = function() { @@ -71,40 +141,12 @@ function (angular, _) { }; $scope.refreshMetricData = function() { - $scope.target.errors = validateTarget($scope.target); - - // this does not work so good - if (!_.isEqual($scope.oldTarget, $scope.target) && _.isEmpty($scope.target.errors)) { + if (!_.isEqual($scope.oldTarget, $scope.target)) { $scope.oldTarget = angular.copy($scope.target); $scope.get_data(); } }; - $scope.suggestDimensionKeys = function(query, callback) { // jshint unused:false - $scope.datasource.getDimensionKeys($scope.target.namespace).then(function(result) { - callback(_.pluck(result, 'text')); - }); - }; - - // TODO: Removed template variables from the suggest - // add this feature back after improving the editor - $scope.suggestDimensionValues = function(query, callback) { - if (!$scope.target.namespace || !$scope.target.metricName) { - return callback([]); - } - - return $scope.datasource.getDimensionValues( - $scope.target.region, - $scope.target.namespace, - $scope.target.metricName, - $scope.target.dimensions - ).then(function(result) { - callback(result); - }, function() { - callback([]); - }); - }; - $scope.addDimension = function() { if (!$scope.addDimensionMode) { $scope.addDimensionMode = true; @@ -147,17 +189,6 @@ function (angular, _) { $scope.refreshMetricData(); }; - // TODO: validate target - function validateTarget() { - var errs = {}; - - if ($scope.target.period < 60 || ($scope.target.period % 60) !== 0) { - errs.period = 'Period must be at least 60 seconds and must be a multiple of 60'; - } - - return errs; - } - $scope.init(); });