Commit 891d7c13 by Torkel Ödegaard

Merge pull request #3205 from mtanda/cloudwatch_suggest_fix

(cloudwatch) fix dimension value suggestion
parents 0011beb6 eb5822bc
...@@ -63,15 +63,10 @@ Name | Description ...@@ -63,15 +63,10 @@ Name | Description
`namespaces()` | Returns a list of namespaces CloudWatch support. `namespaces()` | Returns a list of namespaces CloudWatch support.
`metrics(namespace)` | Returns a list of metrics in the namespace. `metrics(namespace)` | Returns a list of metrics in the namespace.
`dimension_keys(namespace)` | Returns a list of dimension keys 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). 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) ![](/img/v2/cloudwatch_templating.png)
## Cost ## Cost
......
...@@ -113,23 +113,28 @@ function (angular, _) { ...@@ -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 = { var request = {
region: templateSrv.replace(region), region: templateSrv.replace(region),
action: 'ListMetrics', action: 'ListMetrics',
parameters: { parameters: {
namespace: templateSrv.replace(namespace), namespace: templateSrv.replace(namespace),
metricName: templateSrv.replace(metricName), metricName: templateSrv.replace(metricName),
dimensions: convertDimensionFormat(dimensions, {}), dimensions: convertDimensionFormat(filterDimensions, {}),
} }
}; };
return this.awsRequest(request).then(function(result) { return this.awsRequest(request).then(function(result) {
return _.chain(result.Metrics).map(function(metric) { return _.chain(result.Metrics)
return _.pluck(metric.Dimensions, 'Value'); .pluck('Dimensions')
}).flatten().uniq().sortBy(function(name) { .flatten()
return name; .filter(function(dimension) {
}).map(function(value) { return dimension.Name === dimensionKey;
})
.pluck('Value')
.uniq()
.sortBy()
.map(function(value) {
return {value: value, text: value}; return {value: value, text: value};
}).value(); }).value();
}); });
...@@ -174,25 +179,14 @@ function (angular, _) { ...@@ -174,25 +179,14 @@ function (angular, _) {
return this.getDimensionKeys(dimensionKeysQuery[1]); 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) { if (dimensionValuesQuery) {
region = templateSrv.replace(dimensionValuesQuery[1]); region = templateSrv.replace(dimensionValuesQuery[1]);
namespace = templateSrv.replace(dimensionValuesQuery[2]); namespace = templateSrv.replace(dimensionValuesQuery[2]);
metricName = templateSrv.replace(dimensionValuesQuery[3]); metricName = templateSrv.replace(dimensionValuesQuery[3]);
var dimensionPart = templateSrv.replace(dimensionValuesQuery[5]); var dimensionKey = templateSrv.replace(dimensionValuesQuery[4]);
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];
});
}
return this.getDimensionValues(region, namespace, metricName, dimensions); return this.getDimensionValues(region, namespace, metricName, dimensionKey, {});
} }
var ebsVolumeIdsQuery = query.match(/^ebs_volume_ids\(([^,]+?),\s?([^,]+?)\)/); var ebsVolumeIdsQuery = query.match(/^ebs_volume_ids\(([^,]+?),\s?([^,]+?)\)/);
...@@ -222,7 +216,7 @@ function (angular, _) { ...@@ -222,7 +216,7 @@ function (angular, _) {
var metricName = 'EstimatedCharges'; var metricName = 'EstimatedCharges';
var dimensions = {}; 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' }; return { status: 'success', message: 'Data source is working', title: 'Success' };
}); });
}; };
......
...@@ -76,7 +76,7 @@ function (angular, _) { ...@@ -76,7 +76,7 @@ function (angular, _) {
} }
}; };
$scope.getDimSegments = function(segment) { $scope.getDimSegments = function(segment, $index) {
if (segment.type === 'operator') { return $q.when([]); } if (segment.type === 'operator') { return $q.when([]); }
var target = $scope.target; var target = $scope.target;
...@@ -85,7 +85,8 @@ function (angular, _) { ...@@ -85,7 +85,8 @@ function (angular, _) {
if (segment.type === 'key' || segment.type === 'plus-button') { if (segment.type === 'key' || segment.type === 'plus-button') {
query = $scope.datasource.getDimensionKeys($scope.target.namespace); query = $scope.datasource.getDimensionKeys($scope.target.namespace);
} else if (segment.type === 'value') { } 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) { return query.then($scope.transformToSegments(true)).then(function(results) {
......
...@@ -165,7 +165,7 @@ describe('CloudWatchDatasource', function() { ...@@ -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.setup(() => {
scenario.requestResponse = { scenario.requestResponse = {
Metrics: [ Metrics: [
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment