From aef644bd21a3c1a5d2b1d5670f5e6cf1db098e8c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Torkel=20=C3=96degaard?= Date: Thu, 8 Oct 2015 13:09:15 +0200 Subject: [PATCH] feat(cloudwatch): final polish to the cloudwatch editor, closes #684 --- .../datasource/cloudwatch/datasource.js | 71 +++++------- .../cloudwatch/partials/query.editor.html | 65 +++-------- .../datasource/cloudwatch/query_ctrl.js | 101 ++++++++---------- .../cloudwatch/specs/datasource_specs.ts | 13 +-- 4 files changed, 95 insertions(+), 155 deletions(-) diff --git a/public/app/plugins/datasource/cloudwatch/datasource.js b/public/app/plugins/datasource/cloudwatch/datasource.js index 12cc611ba7e..9a9876b53ae 100644 --- a/public/app/plugins/datasource/cloudwatch/datasource.js +++ b/public/app/plugins/datasource/cloudwatch/datasource.js @@ -35,7 +35,7 @@ function (angular, _) { query.namespace = templateSrv.replace(target.namespace, options.scopedVars); query.metricName = templateSrv.replace(target.metricName, options.scopedVars); query.dimensions = convertDimensionFormat(target.dimensions); - query.statistics = getActivatedStatistics(target.statistics); + query.statistics = target.statistics; query.period = parseInt(target.period, 10); var range = end - start; @@ -191,7 +191,7 @@ function (angular, _) { }); } - return this.getDimensionValues(region, namespace, metricName, dimensions).then(transformSuggestData); + return this.getDimensionValues(region, namespace, metricName, dimensions); } var ebsVolumeIdsQuery = query.match(/^ebs_volume_ids\(([^,]+?),\s?([^,]+?)\)/); @@ -243,52 +243,33 @@ function (angular, _) { }; function transformMetricData(md, options) { - var result = []; + var aliasRegex = /\{\{(.+?)\}\}/g; + var aliasPattern = options.alias || '{{metric}}_{{stat}}'; + var aliasData = { + region: templateSrv.replace(options.region), + namespace: templateSrv.replace(options.namespace), + metric: templateSrv.replace(options.metricName), + }; + _.extend(aliasData, options.dimensions); - console.log(options); - var dimensionPart = templateSrv.replace(JSON.stringify(options.dimensions)); - _.each(getActivatedStatistics(options.statistics), function(s) { - var originalSettings = _.templateSettings; - _.templateSettings = { - interpolate: /\{\{(.+?)\}\}/g - }; - var template = _.template(options.legendFormat); + return _.map(options.statistics, function(stat) { + var dps = _.chain(md.Datapoints).map(function(dp) { + return [dp[stat], new Date(dp.Timestamp).getTime()]; + }) + .sortBy(function(dp) { + return dp[1]; + }).value(); - var metricLabel; - if (_.isEmpty(options.legendFormat)) { - metricLabel = md.Label + '_' + s + dimensionPart; - } else { - var d = convertDimensionFormat(options.dimensions); - metricLabel = template({ - Region: templateSrv.replace(options.region), - Namespace: templateSrv.replace(options.namespace), - MetricName: templateSrv.replace(options.metricName), - Dimensions: d, - Statistics: s - }); - } - - _.templateSettings = originalSettings; - - var dps = _.map(md.Datapoints, function(value) { - return [value[s], new Date(value.Timestamp).getTime()]; + aliasData.stat = stat; + var seriesName = aliasPattern.replace(aliasRegex, function(match, g1) { + if (aliasData[g1]) { + return aliasData[g1]; + } + return g1; }); - dps = _.sortBy(dps, function(dp) { return dp[1]; }); - result.push({ target: metricLabel, datapoints: dps }); + return {target: seriesName, datapoints: dps}; }); - - return result; - } - - function getActivatedStatistics(statistics) { - var activatedStatistics = []; - _.each(statistics, function(v, k) { - if (v) { - activatedStatistics.push(k); - } - }); - return activatedStatistics; } function convertToCloudWatchTime(date) { @@ -296,10 +277,10 @@ function (angular, _) { } function convertDimensionFormat(dimensions) { - return _.map(_.keys(dimensions), function(key) { + return _.map(dimensions, function(value, key) { return { Name: templateSrv.replace(key), - Value: templateSrv.replace(dimensions[key]) + Value: templateSrv.replace(value) }; }); } diff --git a/public/app/plugins/datasource/cloudwatch/partials/query.editor.html b/public/app/plugins/datasource/cloudwatch/partials/query.editor.html index 674ab2e4462..80491a284f6 100644 --- a/public/app/plugins/datasource/cloudwatch/partials/query.editor.html +++ b/public/app/plugins/datasource/cloudwatch/partials/query.editor.html @@ -33,7 +33,7 @@
@@ -52,70 +58,33 @@
+
- -
-
- -
-
diff --git a/public/app/plugins/datasource/cloudwatch/query_ctrl.js b/public/app/plugins/datasource/cloudwatch/query_ctrl.js index 5a1a34e7d5b..ccbc36f0912 100644 --- a/public/app/plugins/datasource/cloudwatch/query_ctrl.js +++ b/public/app/plugins/datasource/cloudwatch/query_ctrl.js @@ -10,12 +10,15 @@ function (angular, _) { 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.period = $scope.target.period || 60; - $scope.target.region = $scope.target.region || $scope.datasource.getDefaultRegion(); + 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 || 60; + 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'); @@ -28,16 +31,48 @@ function (angular, _) { return memo; }, []); - $scope.fixSegments(); + $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.fixSegments = function() { - var count = $scope.dimSegments.length; - var lastSegment = $scope.dimSegments[Math.max(count-1, 0)]; + $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') { - $scope.dimSegments.push(uiSegmentSrv.newPlusButton()); + segments.push(uiSegmentSrv.newPlusButton()); } }; @@ -74,8 +109,8 @@ function (angular, _) { segment.cssClass = 'query-segment-key'; } - $scope.fixSegments(); $scope.syncDimSegmentsWithModel(); + $scope.ensurePlusButton($scope.dimSegments); $scope.get_data(); }; @@ -147,48 +182,6 @@ function (angular, _) { } }; - $scope.addDimension = function() { - if (!$scope.addDimensionMode) { - $scope.addDimensionMode = true; - return; - } - - if (!$scope.target.dimensions) { - $scope.target.dimensions = {}; - } - - $scope.target.dimensions[$scope.target.currentDimensionKey] = $scope.target.currentDimensionValue; - $scope.target.escapedDimensions = this.escapeDimensions($scope.target.dimensions); - $scope.target.currentDimensionKey = ''; - $scope.target.currentDimensionValue = ''; - $scope.refreshMetricData(); - - $scope.addDimensionMode = false; - }; - - $scope.removeDimension = function(key) { - key = key.replace(/\\\$/g, '$'); - delete $scope.target.dimensions[key]; - $scope.target.escapedDimensions = this.escapeDimensions($scope.target.dimensions); - $scope.refreshMetricData(); - }; - - $scope.escapeDimensions = function(d) { - var result = {}; - _.chain(d) - .keys(d) - .each(function(k) { - var v = d[k]; - result[k.replace(/\$/g, '\uFF04')] = v.replace(/\$/g, '\$'); - }); - - return result; - }; - - $scope.statisticsOptionChanged = function() { - $scope.refreshMetricData(); - }; - $scope.init(); }); diff --git a/public/app/plugins/datasource/cloudwatch/specs/datasource_specs.ts b/public/app/plugins/datasource/cloudwatch/specs/datasource_specs.ts index 03b35a7bf8d..4714a642d30 100644 --- a/public/app/plugins/datasource/cloudwatch/specs/datasource_specs.ts +++ b/public/app/plugins/datasource/cloudwatch/specs/datasource_specs.ts @@ -34,9 +34,7 @@ describe('CloudWatchDatasource', function() { dimensions: { InstanceId: 'i-12345678' }, - statistics: { - Average: true - }, + statistics: ['Average'], period: 300 } ] @@ -66,7 +64,7 @@ describe('CloudWatchDatasource', function() { expect(params.metricName).to.be(query.targets[0].metricName); expect(params.dimensions[0].Name).to.be(Object.keys(query.targets[0].dimensions)[0]); expect(params.dimensions[0].Value).to.be(query.targets[0].dimensions[Object.keys(query.targets[0].dimensions)[0]]); - expect(params.statistics).to.eql(Object.keys(query.targets[0].statistics)); + expect(params.statistics).to.eql(query.targets[0].statistics); expect(params.period).to.be(query.targets[0].period); done(); }); @@ -75,9 +73,8 @@ describe('CloudWatchDatasource', function() { it('should return series list', function(done) { ctx.ds.query(query).then(function(result) { - var s = Object.keys(query.targets[0].statistics)[0]; - expect(result.data[0].target).to.be(response.Label + '_' + s + JSON.stringify(query.targets[0].dimensions)); - expect(result.data[0].datapoints[0][0]).to.be(response.Datapoints[0][s]); + expect(result.data[0].target).to.be('CPUUtilization_Average'); + expect(result.data[0].datapoints[0][0]).to.be(response.Datapoints[0]['Average']); done(); }); ctx.$rootScope.$apply(); @@ -167,7 +164,7 @@ describe('CloudWatchDatasource', function() { }; }); - it('should call __GetMetrics and return result', () => { + it('should call __ListMetrics and return result', () => { expect(scenario.result[0].text).to.be('i-12345678'); expect(scenario.request.data.action).to.be('ListMetrics'); });