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:
parent
1381a694b7
commit
bc56847bc9
@ -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++) {
|
||||||
|
@ -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'};
|
|
||||||
});
|
|
||||||
|
|
||||||
});
|
|
@ -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
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
29
partials/annotations.editor.html
Normal file
29
partials/annotations.editor.html
Normal 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>
|
@ -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",
|
||||||
|
Loading…
x
Reference in New Issue
Block a user