Update datasource for group_by api changes
Change-Id: I1339c11d5b7bc4c231f6668004077ac8c27e3db2
This commit is contained in:
parent
bc56847bc9
commit
7f08241c49
232
datasource.js
232
datasource.js
|
@ -44,13 +44,10 @@ function (angular, _, moment, sdk, dateMath, kbn) {
|
||||||
}
|
}
|
||||||
var query = this.buildDataQuery(options.targets[i], from, to);
|
var query = this.buildDataQuery(options.targets[i], from, to);
|
||||||
query = self.templateSrv.replace(query, options.scopedVars);
|
query = self.templateSrv.replace(query, options.scopedVars);
|
||||||
var query_list;
|
var query_list = this.expandTemplatedQueries(query);
|
||||||
if (options.group){
|
// Pre query aliasing
|
||||||
query_list = this.expandTemplatedQueries(query);
|
// Used when querying with group_by, where some dimensions are not returned
|
||||||
}
|
query_list = query_list.map(datasource.autoAlias);
|
||||||
else {
|
|
||||||
query_list = this.expandQueries(query);
|
|
||||||
}
|
|
||||||
targets_list.push(query_list);
|
targets_list.push(query_list);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -112,32 +109,38 @@ function (angular, _, moment, sdk, dateMath, kbn) {
|
||||||
MonascaDatasource.prototype.buildDataQuery = function(options, from, to) {
|
MonascaDatasource.prototype.buildDataQuery = function(options, from, to) {
|
||||||
var params = {};
|
var params = {};
|
||||||
params.name = options.metric;
|
params.name = options.metric;
|
||||||
if (options.group) {
|
|
||||||
params.group_by = '*';
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
params.merge_metrics = 'true';
|
|
||||||
}
|
|
||||||
params.start_time = from;
|
params.start_time = from;
|
||||||
if (to) {
|
if (to) {
|
||||||
params.end_time = to;
|
params.end_time = to;
|
||||||
}
|
}
|
||||||
if (options.dimensions) {
|
if (options.dimensions) {
|
||||||
var dimensions = '';
|
var dimensions = [];
|
||||||
|
var group_by = [];
|
||||||
for (var i = 0; i < options.dimensions.length; i++) {
|
for (var i = 0; i < options.dimensions.length; i++) {
|
||||||
var key = options.dimensions[i].key;
|
var key = options.dimensions[i].key;
|
||||||
var value = options.dimensions[i].value;
|
var value = options.dimensions[i].value;
|
||||||
if (options.group && value == '$all') {
|
if (value == '$all' || value =='*') {
|
||||||
continue;
|
group_by.push(key);
|
||||||
}
|
}
|
||||||
if (dimensions) {
|
else {
|
||||||
dimensions += ',';
|
dimensions.push(key + ':' + value);
|
||||||
}
|
}
|
||||||
dimensions += key;
|
|
||||||
dimensions += ':';
|
|
||||||
dimensions += value;
|
|
||||||
}
|
}
|
||||||
params.dimensions = dimensions;
|
var dimensions_string = dimensions.join(',');
|
||||||
|
var group_by_string = group_by.join(',');
|
||||||
|
if (dimensions_string){
|
||||||
|
params.dimensions = dimensions;
|
||||||
|
}
|
||||||
|
if (group_by_string){
|
||||||
|
params.group_by = group_by;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (options.group) {
|
||||||
|
params.group_by = '*';
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
params.merge_metrics = 'true';
|
||||||
}
|
}
|
||||||
if (options.alias) {
|
if (options.alias) {
|
||||||
params.alias = options.alias;
|
params.alias = options.alias;
|
||||||
|
@ -146,39 +149,17 @@ function (angular, _, moment, sdk, dateMath, kbn) {
|
||||||
if (options.aggregator && options.aggregator != 'none') {
|
if (options.aggregator && options.aggregator != 'none') {
|
||||||
params.statistics = options.aggregator;
|
params.statistics = options.aggregator;
|
||||||
params.period = options.period;
|
params.period = options.period;
|
||||||
path = '/v2.0/metrics/statistics';
|
path = '/v2.0/metrics/statistics?';
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
path = '/v2.0/metrics/measurements';
|
path = '/v2.0/metrics/measurements?';
|
||||||
}
|
}
|
||||||
var first = true;
|
path += Object.keys(params).map(function(key) {
|
||||||
Object.keys(params).forEach(function (key) {
|
return key + '=' + params[key];
|
||||||
if (first) {
|
}).join('&');
|
||||||
path += '?';
|
|
||||||
first = false;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
path += '&';
|
|
||||||
}
|
|
||||||
path += key;
|
|
||||||
path += '=';
|
|
||||||
path += params[key];
|
|
||||||
});
|
|
||||||
return path;
|
return path;
|
||||||
};
|
};
|
||||||
|
|
||||||
MonascaDatasource.prototype.expandQueries = function(query) {
|
|
||||||
var datasource = this;
|
|
||||||
return this.expandAllQueries(query).then(function(partial_query_list) {
|
|
||||||
var query_list = [];
|
|
||||||
for (var i = 0; i < partial_query_list.length; i++) {
|
|
||||||
query_list = query_list.concat(datasource.expandTemplatedQueries(partial_query_list[i]));
|
|
||||||
}
|
|
||||||
query_list = datasource.autoAlias(query_list);
|
|
||||||
return query_list;
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
MonascaDatasource.prototype.expandTemplatedQueries = function(query) {
|
MonascaDatasource.prototype.expandTemplatedQueries = function(query) {
|
||||||
var templated_vars = query.match(/{[^}]*}/g);
|
var templated_vars = query.match(/{[^}]*}/g);
|
||||||
if (!templated_vars) {
|
if (!templated_vars) {
|
||||||
|
@ -196,62 +177,7 @@ function (angular, _, moment, sdk, dateMath, kbn) {
|
||||||
return expandedQueries;
|
return expandedQueries;
|
||||||
};
|
};
|
||||||
|
|
||||||
MonascaDatasource.prototype.expandAllQueries = function(query) {
|
MonascaDatasource.prototype.autoAlias = function(query, dimensions, return_target) {
|
||||||
if (query.indexOf("$all") > -1) {
|
|
||||||
var metric_name = query.match(/name=([^&]*)/)[1];
|
|
||||||
var start_time = query.match(/start_time=([^&]*)/)[1];
|
|
||||||
|
|
||||||
// Find all matching subqueries
|
|
||||||
var dimregex = /(?:dimensions=|,)([^,]*):\$all/g;
|
|
||||||
var matches, neededDimensions = [];
|
|
||||||
while (matches = dimregex.exec(query)) {
|
|
||||||
neededDimensions.push(matches[1]);
|
|
||||||
}
|
|
||||||
|
|
||||||
var metricQueryParams = {'name' : metric_name, 'start_time': start_time};
|
|
||||||
var queriesPromise = this.metricsQuery(metricQueryParams).then(function(data) {
|
|
||||||
var expandedQueries = [];
|
|
||||||
var metrics = data.data.elements;
|
|
||||||
var matchingMetrics = {}; // object ensures uniqueness of dimension sets
|
|
||||||
for (var i = 0; i < metrics.length; i++) {
|
|
||||||
var dimensions = metrics[i].dimensions;
|
|
||||||
var set = {};
|
|
||||||
var skip = false;
|
|
||||||
for (var j = 0; j < neededDimensions.length; j++) {
|
|
||||||
var key = neededDimensions[j];
|
|
||||||
if (!(key in dimensions)) {
|
|
||||||
skip = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
set[key] = dimensions[key];
|
|
||||||
}
|
|
||||||
if (!skip) {
|
|
||||||
matchingMetrics[JSON.stringify(set)] = set;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Object.keys(matchingMetrics).forEach(function (set) {
|
|
||||||
var new_query = query;
|
|
||||||
var match = matchingMetrics[set];
|
|
||||||
Object.keys(match).forEach(function (key) {
|
|
||||||
var to_replace = key+":\\$all";
|
|
||||||
var replacement = key+":"+match[key];
|
|
||||||
new_query = new_query.replace(new RegExp(to_replace, 'g'), replacement);
|
|
||||||
});
|
|
||||||
expandedQueries.push(new_query);
|
|
||||||
});
|
|
||||||
return expandedQueries;
|
|
||||||
});
|
|
||||||
|
|
||||||
return queriesPromise;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
return self.q.resolve([query]);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// Alias based on dimensions in query
|
|
||||||
// Used when querying with merge flag, where no dimension info is returned.
|
|
||||||
MonascaDatasource.prototype.autoAlias = function(query_list) {
|
|
||||||
function keysSortedByLengthDesc(obj) {
|
function keysSortedByLengthDesc(obj) {
|
||||||
var keys = [];
|
var keys = [];
|
||||||
for (var key in obj) {
|
for (var key in obj) {
|
||||||
|
@ -261,68 +187,62 @@ function (angular, _, moment, sdk, dateMath, kbn) {
|
||||||
return keys.sort(byLength);
|
return keys.sort(byLength);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (var i = 0; i < query_list.length; i++) {
|
if (typeof(dimensions) !== "object") {
|
||||||
var query = query_list[i];
|
var dimensions_string = query.match(/dimensions=([^&]*)/);
|
||||||
var alias = query.match(/alias=[^&@]*@([^&]*)/);
|
if (dimensions_string) {
|
||||||
var dimensions = query.match(/dimensions=([^&]*)/);
|
var dimensions_list = dimensions_string[1].split(',');
|
||||||
if (alias && dimensions[1]) {
|
dimensions = {};
|
||||||
var dimensions_list = dimensions[1].split(',');
|
|
||||||
var dimensions_dict = {};
|
|
||||||
for (var j = 0; j < dimensions_list.length; j++) {
|
for (var j = 0; j < dimensions_list.length; j++) {
|
||||||
var dim = dimensions_list[j].split(':');
|
var dim = dimensions_list[j].split(':');
|
||||||
dimensions_dict[dim[0]] = dim[1];
|
dimensions[dim[0]] = dim[1];
|
||||||
}
|
}
|
||||||
var keys = keysSortedByLengthDesc(dimensions_dict);
|
|
||||||
for (var k in keys) {
|
|
||||||
query = query.replace(new RegExp("@"+keys[k], 'g'), dimensions_dict[keys[k]]);
|
|
||||||
}
|
|
||||||
query_list[i] = query;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return query_list;
|
|
||||||
|
var target = null;
|
||||||
|
var alias_string = query.match(/alias=[^&]*/);
|
||||||
|
if (alias_string) {
|
||||||
|
var alias = alias_string[0];
|
||||||
|
var keys = keysSortedByLengthDesc(dimensions);
|
||||||
|
for (var k in keys) {
|
||||||
|
alias = alias.replace(new RegExp("@"+keys[k], 'g'), dimensions[keys[k]]);
|
||||||
|
}
|
||||||
|
query = query.replace(alias_string[0], alias);
|
||||||
|
target = alias.match(/alias=(.*)/)[1];
|
||||||
|
}
|
||||||
|
if (return_target === true) {
|
||||||
|
return target;
|
||||||
|
}
|
||||||
|
return query;
|
||||||
};
|
};
|
||||||
|
|
||||||
MonascaDatasource.prototype.convertDataPoints = function(data) {
|
MonascaDatasource.prototype.convertDataPoints = function(data) {
|
||||||
function keysSortedByLengthDesc(obj) {
|
|
||||||
var keys = [];
|
|
||||||
for (var key in obj) {
|
|
||||||
keys.push(key);
|
|
||||||
}
|
|
||||||
function byLength(a, b) {return b.length - a.length;}
|
|
||||||
return keys.sort(byLength);
|
|
||||||
}
|
|
||||||
|
|
||||||
var url = data.config.url;
|
var url = data.config.url;
|
||||||
var results = [];
|
var results = [];
|
||||||
|
|
||||||
for (var i = 0; i < data.data.elements.length; i++)
|
for (var i = 0; i < data.data.elements.length; i++)
|
||||||
{
|
{
|
||||||
var element = data.data.elements[i];
|
var element = data.data.elements[i];
|
||||||
|
|
||||||
var target = element.name;
|
var target = element.name;
|
||||||
var alias = data.config.url.match(/alias=([^&]*)/);
|
|
||||||
// Alias based on returned dimensions
|
// Post query aliasing
|
||||||
// Used when querying with group_by flag where dimensions are not specified in initial query
|
// Used when querying with group_by flag where dimensions are not specified in initial query
|
||||||
|
var alias = self.autoAlias(data.config.url, element.dimensions, true);
|
||||||
if (alias) {
|
if (alias) {
|
||||||
alias = alias[1];
|
|
||||||
var keys = keysSortedByLengthDesc(element.dimensions);
|
|
||||||
for (var k in keys)
|
|
||||||
{
|
|
||||||
alias = alias.replace(new RegExp("@"+keys[k], 'g'), element.dimensions[keys[k]]);
|
|
||||||
}
|
|
||||||
target = alias;
|
target = alias;
|
||||||
}
|
}
|
||||||
|
|
||||||
var raw_datapoints;
|
var raw_datapoints;
|
||||||
var aggregator;
|
var aggregator = 'value';
|
||||||
if ('measurements' in element) {
|
if ('measurements' in element) {
|
||||||
raw_datapoints = element.measurements;
|
raw_datapoints = element.measurements;
|
||||||
aggregator = 'value';
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
raw_datapoints = element.statistics;
|
raw_datapoints = element.statistics;
|
||||||
aggregator = url.match(/statistics=[^&]*/);
|
if (element.columns.indexOf(aggregator) < 0) {
|
||||||
aggregator = aggregator[0].substring('statistics='.length);
|
aggregator = url.match(/statistics=[^&]*/);
|
||||||
|
aggregator = aggregator[0].substring('statistics='.length);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
var datapoints = [];
|
var datapoints = [];
|
||||||
var timeCol = element.columns.indexOf('timestamp');
|
var timeCol = element.columns.indexOf('timestamp');
|
||||||
|
@ -373,26 +293,6 @@ function (angular, _, moment, sdk, dateMath, kbn) {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// Handle incosistent element.id from merging here. Remove when this bug is fixed.
|
|
||||||
function flattenResults() {
|
|
||||||
var elements = [];
|
|
||||||
for (var i = 0; i < element_list.length; i++) {
|
|
||||||
var element = element_list[i];
|
|
||||||
if (element.measurements){
|
|
||||||
elements.push(element.measurements);
|
|
||||||
}
|
|
||||||
if (element.statistics){
|
|
||||||
elements.push(element.statistics);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (data.data.elements[0].measurements){
|
|
||||||
data.data.elements[0].measurements = _.flatten(elements, true);
|
|
||||||
}
|
|
||||||
if (data.data.elements[0].statistics){
|
|
||||||
data.data.elements[0].statistics = _.flatten(elements, true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function requestAll(multi_page){
|
function requestAll(multi_page){
|
||||||
datasource._monascaRequest(path, params)
|
datasource._monascaRequest(path, params)
|
||||||
.then(function(d) {
|
.then(function(d) {
|
||||||
|
@ -409,13 +309,8 @@ function (angular, _, moment, sdk, dateMath, kbn) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Handle incosistent element.id from merging here. Remove when this bug is fixed.
|
|
||||||
var query = d.data.links[0].href;
|
|
||||||
if (multi_page){
|
if (multi_page){
|
||||||
if (query.indexOf('merge_metrics') > -1) {
|
if (aggregate){
|
||||||
flattenResults();
|
|
||||||
}
|
|
||||||
else if (aggregate){
|
|
||||||
aggregateResults();
|
aggregateResults();
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
@ -464,6 +359,7 @@ function (angular, _, moment, sdk, dateMath, kbn) {
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Called by grafana to retrieve possible query template options
|
||||||
MonascaDatasource.prototype.metricFindQuery = function(query) {
|
MonascaDatasource.prototype.metricFindQuery = function(query) {
|
||||||
return this.dimensionValuesQuery({'dimension_name': query}).then(function(data) {
|
return this.dimensionValuesQuery({'dimension_name': query}).then(function(data) {
|
||||||
return _.map(data, function(value) {
|
return _.map(data, function(value) {
|
||||||
|
@ -472,6 +368,7 @@ function (angular, _, moment, sdk, dateMath, kbn) {
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Called by grafana to retrieve data for dispalying annotations
|
||||||
MonascaDatasource.prototype.annotationQuery = function(options) {
|
MonascaDatasource.prototype.annotationQuery = function(options) {
|
||||||
var dimensions = [];
|
var dimensions = [];
|
||||||
if (options.annotation.dimensions) {
|
if (options.annotation.dimensions) {
|
||||||
|
@ -511,6 +408,7 @@ function (angular, _, moment, sdk, dateMath, kbn) {
|
||||||
return template_list;
|
return template_list;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Called by grafana to test the datasource
|
||||||
MonascaDatasource.prototype.testDatasource = function() {
|
MonascaDatasource.prototype.testDatasource = function() {
|
||||||
return this.namesQuery().then(function () {
|
return this.namesQuery().then(function () {
|
||||||
return { status: 'success', message: 'Data source is working', title: 'Success' };
|
return { status: 'success', message: 'Data source is working', title: 'Success' };
|
||||||
|
|
|
@ -66,7 +66,7 @@
|
||||||
<gf-form-switch
|
<gf-form-switch
|
||||||
class="gf-form"
|
class="gf-form"
|
||||||
label-class="gf-form-label query-keyword"
|
label-class="gf-form-label query-keyword"
|
||||||
label="Group_by"
|
label="Group_by=*"
|
||||||
checked="ctrl.target.group"
|
checked="ctrl.target.group"
|
||||||
on-change="ctrl.targetBlur()"
|
on-change="ctrl.targetBlur()"
|
||||||
switch-class="max-width-6"></gf-form-switch>
|
switch-class="max-width-6"></gf-form-switch>
|
||||||
|
|
|
@ -28,7 +28,7 @@
|
||||||
<h5>Dimensions Templating</h5>
|
<h5>Dimensions Templating</h5>
|
||||||
<ul ng-non-bindable>
|
<ul ng-non-bindable>
|
||||||
<li>Template variables can be used as normal</li>
|
<li>Template variables can be used as normal</li>
|
||||||
<li>$all : Use as a dimension value to automatically group the query by all valid values for the dimension</li>
|
<li>$all/* : Use as a dimension value to automatically group the query by all valid values for the dimension</li>
|
||||||
<li>When 'group_by' is selected, $all will be ignored, and the query will group the data on all unspecified dimensions</li>
|
<li>When 'group_by' is selected, $all will be ignored, and the query will group the data on all unspecified dimensions</li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
|
|
Loading…
Reference in New Issue