Add annotation support for monasca plugin

Includes cleanup of datasource.js
Also removes directives.js as it is no longer used

Change-Id: I032c937a1360f9fe75e6ad0a762ceee46256f8c6
This commit is contained in:
Ryan Bak 2016-10-18 15:40:09 -06:00
parent 1381a694b7
commit bc56847bc9
5 changed files with 100 additions and 49 deletions

View File

@ -39,13 +39,12 @@ function (angular, _, moment, sdk, dateMath, kbn) {
var targets_list = []; var targets_list = [];
for (var i = 0; i < options.targets.length; i++) { for (var i = 0; i < options.targets.length; i++) {
var target = options.targets[i]; var target = options.targets[i];
// Missing target.period indicates a new unfilled query if (target.error || target.hide || !target.metric) {
if (target.error || target.hide || !target.period) {
continue; continue;
} }
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;
if (options.group){ if (options.group){
query_list = this.expandTemplatedQueries(query); query_list = this.expandTemplatedQueries(query);
} }
@ -62,9 +61,9 @@ function (angular, _, moment, sdk, dateMath, kbn) {
var promises = self.q.resolve(targets_promise).then(function(targets) { var promises = self.q.resolve(targets_promise).then(function(targets) {
return targets.map(function (target) { return targets.map(function (target) {
target = datasource.convertPeriod(target); target = datasource.convertPeriod(target);
return datasource._limitedMonascaRequest(target, {}, true).then(datasource.convertDataPoints).catch(function(err) {throw err}); return datasource._limitedMonascaRequest(target, {}, true).then(datasource.convertDataPoints).catch(function(err) {throw err;});
}); });
}).catch(function(err) {throw err}); }).catch(function(err) {throw err;});
return self.q.resolve(promises).then(function(promises) { return self.q.resolve(promises).then(function(promises) {
return self.q.all(promises).then(function(results) { return self.q.all(promises).then(function(results) {
@ -73,7 +72,7 @@ function (angular, _, moment, sdk, dateMath, kbn) {
return a.target.localeCompare(b.target); return a.target.localeCompare(b.target);
}); });
}); });
return { data: _.flatten(sorted_results).filter(function(result) { return !_.isEmpty(result)}) }; return { data: _.flatten(sorted_results).filter(function(result) { return !_.isEmpty(result);}) };
}); });
}); });
}; };
@ -92,7 +91,7 @@ function (angular, _, moment, sdk, dateMath, kbn) {
MonascaDatasource.prototype.dimensionNamesQuery = function(params) { MonascaDatasource.prototype.dimensionNamesQuery = function(params) {
var datasource = this; var datasource = this;
return this._limitedMonascaRequest('/v2.0/metrics/dimensions/names', params, false).then(function(data) { return this._limitedMonascaRequest('/v2.0/metrics/dimensions/names', params, false).then(function(data) {
return datasource.convertDataList(data, 'dimension_name') return datasource.convertDataList(data, 'dimension_name');
}).catch(function(err) {throw err;}); }).catch(function(err) {throw err;});
}; };
@ -144,7 +143,7 @@ function (angular, _, moment, sdk, dateMath, kbn) {
params.alias = options.alias; params.alias = options.alias;
} }
var path; var path;
if (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';
@ -256,11 +255,11 @@ function (angular, _, moment, sdk, dateMath, kbn) {
function keysSortedByLengthDesc(obj) { function keysSortedByLengthDesc(obj) {
var keys = []; var keys = [];
for (var key in obj) { for (var key in obj) {
keys.push(key) keys.push(key);
} }
function byLength(a, b) {return b.length - a.length} function byLength(a, b) {return b.length - a.length;}
return keys.sort(byLength) return keys.sort(byLength);
}; }
for (var i = 0; i < query_list.length; i++) { for (var i = 0; i < query_list.length; i++) {
var query = query_list[i]; var query = query_list[i];
@ -287,11 +286,11 @@ function (angular, _, moment, sdk, dateMath, kbn) {
function keysSortedByLengthDesc(obj) { function keysSortedByLengthDesc(obj) {
var keys = []; var keys = [];
for (var key in obj) { for (var key in obj) {
keys.push(key) keys.push(key);
} }
function byLength(a, b) {return b.length - a.length} function byLength(a, b) {return b.length - a.length;}
return keys.sort(byLength) return keys.sort(byLength);
}; }
var url = data.config.url; var url = data.config.url;
var results = []; var results = [];
@ -309,9 +308,9 @@ function (angular, _, moment, sdk, dateMath, kbn) {
var keys = keysSortedByLengthDesc(element.dimensions); var keys = keysSortedByLengthDesc(element.dimensions);
for (var k in keys) for (var k in keys)
{ {
alias = alias.replace(new RegExp("@"+keys[k], 'g'), element.dimensions[keys[k]]) alias = alias.replace(new RegExp("@"+keys[k], 'g'), element.dimensions[keys[k]]);
} }
target = alias target = alias;
} }
var raw_datapoints; var raw_datapoints;
@ -328,14 +327,19 @@ function (angular, _, moment, sdk, dateMath, kbn) {
var datapoints = []; var datapoints = [];
var timeCol = element.columns.indexOf('timestamp'); var timeCol = element.columns.indexOf('timestamp');
var dataCol = element.columns.indexOf(aggregator); var dataCol = element.columns.indexOf(aggregator);
var metaCol = element.columns.indexOf('value_meta');
for (var j = 0; j < raw_datapoints.length; j++) { for (var j = 0; j < raw_datapoints.length; j++) {
var datapoint = raw_datapoints[j]; var datapoint = raw_datapoints[j];
var time = new Date(datapoint[timeCol]); var time = new Date(datapoint[timeCol]);
var point = datapoint[dataCol]; var point = datapoint[dataCol];
datapoints.push([point, time.getTime()]); var newpoint = [point, time.getTime()];
if (metaCol >= 0) {
newpoint.push(datapoint[metaCol]);
}
datapoints.push(newpoint);
} }
var convertedData = { 'target': target, 'datapoints': datapoints }; var convertedData = { 'target': target, 'datapoints': datapoints };
results.push(convertedData) results.push(convertedData);
} }
return results; return results;
}; };
@ -382,22 +386,22 @@ function (angular, _, moment, sdk, dateMath, kbn) {
} }
} }
if (data.data.elements[0].measurements){ if (data.data.elements[0].measurements){
data.data.elements[0].measurements = _.flatten(elements, true) data.data.elements[0].measurements = _.flatten(elements, true);
} }
if (data.data.elements[0].statistics){ if (data.data.elements[0].statistics){
data.data.elements[0].statistics = _.flatten(elements, true) 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) {
data = d data = d;
element_list = element_list.concat(d.data.elements); element_list = element_list.concat(d.data.elements);
if(d.data.links) { if(d.data.links) {
for (var i = 0; i < d.data.links.length; i++) { for (var i = 0; i < d.data.links.length; i++) {
if (d.data.links[i].rel == 'next'){ if (d.data.links[i].rel == 'next'){
var next = decodeURIComponent(d.data.links[i].href) var next = decodeURIComponent(d.data.links[i].href);
var offset = next.match(/offset=([^&]*)/); var offset = next.match(/offset=([^&]*)/);
params.offset = offset[1]; params.offset = offset[1];
requestAll(true); requestAll(true);
@ -406,7 +410,7 @@ function (angular, _, moment, sdk, dateMath, kbn) {
} }
} }
// Handle incosistent element.id from merging here. Remove when this bug is fixed. // Handle incosistent element.id from merging here. Remove when this bug is fixed.
var query = d.data.links[0].href var query = d.data.links[0].href;
if (multi_page){ if (multi_page){
if (query.indexOf('merge_metrics') > -1) { if (query.indexOf('merge_metrics') > -1) {
flattenResults(); flattenResults();
@ -419,7 +423,7 @@ function (angular, _, moment, sdk, dateMath, kbn) {
} }
} }
deferred.resolve(data); deferred.resolve(data);
}).catch(function(err) {deferred.reject(err)}); }).catch(function(err) {deferred.reject(err);});
} }
requestAll(false); requestAll(false);
@ -442,13 +446,13 @@ function (angular, _, moment, sdk, dateMath, kbn) {
return this.backendSrv.datasourceRequest(options).catch(function(err) { return this.backendSrv.datasourceRequest(options).catch(function(err) {
if (err.status !== 0 || err.status >= 300) { if (err.status !== 0 || err.status >= 300) {
var monasca_response var monasca_response;
if (err.data) { if (err.data) {
if (err.data.message){ if (err.data.message){
monasca_response = err.data.message; monasca_response = err.data.message;
} else{ } else{
var err_name = Object.keys(err.data)[0] var err_name = Object.keys(err.data)[0];
monasca_response = err.data[err_name].message monasca_response = err.data[err_name].message;
} }
} }
if (monasca_response) { if (monasca_response) {
@ -468,6 +472,37 @@ function (angular, _, moment, sdk, dateMath, kbn) {
}); });
}; };
MonascaDatasource.prototype.annotationQuery = function(options) {
var dimensions = [];
if (options.annotation.dimensions) {
options.annotation.dimensions.split(',').forEach(function(x){
var dim = x.split('=');
dimensions.push({'key': dim[0], 'value': dim[1]});
});
}
options.targets = [{ 'metric': options.annotation.metric, 'dimensions': dimensions}];
return this.query(options).then(function(result) {
var list = [];
for (var i = 0; i < result.data.length; i++) {
var target = result.data[i];
for (var y = 0; y < target.datapoints.length; y++) {
var datapoint = target.datapoints[y];
if (!datapoint[0] && !options.annotation.shownull) { continue; }
var event = {
annotation: options.annotation,
time: datapoint[1],
title: target.target
};
if (datapoint.length > 2 && options.annotation.showmeta){ // value_meta exists
event.text = datapoint[2].detail;
}
list.push(event);
}
}
return list;
});
};
MonascaDatasource.prototype.listTemplates = function() { MonascaDatasource.prototype.listTemplates = function() {
var template_list = []; var template_list = [];
for (var i = 0; i < self.templateSrv.variables.length; i++) { for (var i = 0; i < self.templateSrv.variables.length; i++) {

View File

@ -1,17 +0,0 @@
define([
'angular',
],
function (angular) {
'use strict';
var module = angular.module('grafana.directives');
module.directive('metricQueryEditorMonasca', function() {
return {controller: 'MonascaQueryCtrl', templateUrl: 'app/plugins/datasource/monasca/partials/query.editor.html'};
});
module.directive('metricQueryOptionsMonasca', function() {
return {templateUrl: 'app/plugins/datasource/monasca/partials/query.options.html'};
});
});

View File

@ -11,10 +11,14 @@ function(MonascaDatasource, MonascaQueryCtrl) {
var MonascaQueryOptionsCtrl = function() {}; var MonascaQueryOptionsCtrl = function() {};
MonascaQueryOptionsCtrl.templateUrl = "partials/query.options.html"; MonascaQueryOptionsCtrl.templateUrl = "partials/query.options.html";
var MonascaAnnotationsQueryCtrl = function() {};
MonascaAnnotationsQueryCtrl.templateUrl = "partials/annotations.editor.html";
return { return {
'Datasource': MonascaDatasource, 'Datasource': MonascaDatasource,
'QueryCtrl': MonascaQueryCtrl, 'QueryCtrl': MonascaQueryCtrl,
'ConfigCtrl': MonascaConfigCtrl, 'ConfigCtrl': MonascaConfigCtrl,
'QueryOptionsCtrl': MonascaQueryOptionsCtrl 'QueryOptionsCtrl': MonascaQueryOptionsCtrl,
'AnnotationsQueryCtrl': MonascaAnnotationsQueryCtrl
}; };
}); });

View File

@ -0,0 +1,29 @@
<div class="gf-form-group">
<div class="gf-form">
<span class="gf-form-label width-13">Metric</span>
<input type="text" class="gf-form-input" ng-model='ctrl.annotation.metric' placeholder=""></input>
</div>
<div class="gf-form">
<span class="gf-form-label width-13">Dimensions</span>
<input type="text" class="gf-form-input" ng-model='ctrl.annotation.dimensions' placeholder="hostname=my-server,region=region1"></input>
</div>
<div class="gf-form">
<gf-form-switch
class="gf-form"
label-class="gf-form-label"
label="Show null values"
checked="ctrl.annotation.shownull"
switch-class="max-width-6">
</gf-form-switch>
<gf-form-switch
class="gf-form"
label-class="gf-form-label"
label="Show value_meta"
checked="ctrl.annotation.showmeta"
switch-class="max-width-6">
</gf-form-switch>
<div class="gf-form gf-form--grow">
<div class="gf-form-label gf-form-label--grow"></div>
</div>
</div>
</div>

View File

@ -10,7 +10,7 @@
}, },
"metrics": true, "metrics": true,
"annotations": false, "annotations": true,
"info": { "info": {
"description": "datasource for the Monasca Api", "description": "datasource for the Monasca Api",