diff --git a/docs/sources/datasources/cloudwatch.md b/docs/sources/datasources/cloudwatch.md index 012da9d843a..4d87c4a0743 100644 --- a/docs/sources/datasources/cloudwatch.md +++ b/docs/sources/datasources/cloudwatch.md @@ -63,15 +63,10 @@ Name | Description `namespaces()` | Returns a list of namespaces CloudWatch support. `metrics(namespace)` | Returns a list of metrics in the namespace. `dimension_keys(namespace)` | Returns a list of dimension keys in the namespace. -`dimension_values(region, namespace, metric)` | Returns a list of dimension values matching the specified `region`, `namespace` and `metric`. +`dimension_values(region, namespace, metric, dimension_key)` | Returns a list of dimension values matching the specified `region`, `namespace`, `metric` and `dimension_key`. For details about the metrics CloudWatch provides, please refer to the [CloudWatch documentation](https://docs.aws.amazon.com/AmazonCloudWatch/latest/DeveloperGuide/CW_Support_For_AWS.html). -If you want to filter dimension values by other dimension key/value pair, you can specify optional parameter like this. -```sql -dimension_values(region, namespace, metric, dim_key1=dim_val1,dim_key2=dim_val2,...) -``` - ![](/img/v2/cloudwatch_templating.png) ## Cost diff --git a/public/app/plugins/datasource/cloudwatch/datasource.js b/public/app/plugins/datasource/cloudwatch/datasource.js index 79f4a6a00c7..da95578782e 100644 --- a/public/app/plugins/datasource/cloudwatch/datasource.js +++ b/public/app/plugins/datasource/cloudwatch/datasource.js @@ -113,23 +113,28 @@ function (angular, _) { }); }; - CloudWatchDatasource.prototype.getDimensionValues = function(region, namespace, metricName, dimensions) { + CloudWatchDatasource.prototype.getDimensionValues = function(region, namespace, metricName, dimensionKey, filterDimensions) { var request = { region: templateSrv.replace(region), action: 'ListMetrics', parameters: { namespace: templateSrv.replace(namespace), metricName: templateSrv.replace(metricName), - dimensions: convertDimensionFormat(dimensions, {}), + dimensions: convertDimensionFormat(filterDimensions, {}), } }; return this.awsRequest(request).then(function(result) { - return _.chain(result.Metrics).map(function(metric) { - return _.pluck(metric.Dimensions, 'Value'); - }).flatten().uniq().sortBy(function(name) { - return name; - }).map(function(value) { + return _.chain(result.Metrics) + .pluck('Dimensions') + .flatten() + .filter(function(dimension) { + return dimension.Name === dimensionKey; + }) + .pluck('Value') + .uniq() + .sortBy() + .map(function(value) { return {value: value, text: value}; }).value(); }); @@ -174,25 +179,14 @@ function (angular, _) { return this.getDimensionKeys(dimensionKeysQuery[1]); } - var dimensionValuesQuery = query.match(/^dimension_values\(([^,]+?),\s?([^,]+?),\s?([^,]+?)(,\s?([^)]*))?\)/); + var dimensionValuesQuery = query.match(/^dimension_values\(([^,]+?),\s?([^,]+?),\s?([^,]+?),\s?([^,]+?)\)/); if (dimensionValuesQuery) { region = templateSrv.replace(dimensionValuesQuery[1]); namespace = templateSrv.replace(dimensionValuesQuery[2]); metricName = templateSrv.replace(dimensionValuesQuery[3]); - var dimensionPart = templateSrv.replace(dimensionValuesQuery[5]); - - 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]; - }); - } + var dimensionKey = templateSrv.replace(dimensionValuesQuery[4]); - return this.getDimensionValues(region, namespace, metricName, dimensions); + return this.getDimensionValues(region, namespace, metricName, dimensionKey, {}); } var ebsVolumeIdsQuery = query.match(/^ebs_volume_ids\(([^,]+?),\s?([^,]+?)\)/); @@ -222,7 +216,7 @@ function (angular, _) { var metricName = 'EstimatedCharges'; var dimensions = {}; - return this.getDimensionValues(region, namespace, metricName, dimensions).then(function () { + return this.getDimensionValues(region, namespace, metricName, 'ServiceName', dimensions).then(function () { return { status: 'success', message: 'Data source is working', title: 'Success' }; }); }; diff --git a/public/app/plugins/datasource/cloudwatch/query_ctrl.js b/public/app/plugins/datasource/cloudwatch/query_ctrl.js index 3869a5ec715..d0f6fe5b52a 100644 --- a/public/app/plugins/datasource/cloudwatch/query_ctrl.js +++ b/public/app/plugins/datasource/cloudwatch/query_ctrl.js @@ -76,7 +76,7 @@ function (angular, _) { } }; - $scope.getDimSegments = function(segment) { + $scope.getDimSegments = function(segment, $index) { if (segment.type === 'operator') { return $q.when([]); } var target = $scope.target; @@ -85,7 +85,8 @@ function (angular, _) { 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, {}); + 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) { diff --git a/public/app/plugins/datasource/cloudwatch/specs/datasource_specs.ts b/public/app/plugins/datasource/cloudwatch/specs/datasource_specs.ts index 39d48e273b3..f3b105c5da5 100644 --- a/public/app/plugins/datasource/cloudwatch/specs/datasource_specs.ts +++ b/public/app/plugins/datasource/cloudwatch/specs/datasource_specs.ts @@ -165,7 +165,7 @@ describe('CloudWatchDatasource', function() { }); }); - describeMetricFindQuery('dimension_values(us-east-1,AWS/EC2,CPUUtilization)', scenario => { + describeMetricFindQuery('dimension_values(us-east-1,AWS/EC2,CPUUtilization,InstanceId)', scenario => { scenario.setup(() => { scenario.requestResponse = { Metrics: [