mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
feat(plugins): migrated opentsdb plugin
This commit is contained in:
parent
2fc8da7a87
commit
0da733de9c
@ -1,3 +1,3 @@
|
|||||||
declare var Datasource: any;
|
declare var OpenTsDatasource: any;
|
||||||
export default Datasource;
|
export {OpenTsDatasource};
|
||||||
|
|
||||||
|
@ -3,13 +3,12 @@ define([
|
|||||||
'lodash',
|
'lodash',
|
||||||
'app/core/utils/datemath',
|
'app/core/utils/datemath',
|
||||||
'moment',
|
'moment',
|
||||||
'./queryCtrl',
|
|
||||||
],
|
],
|
||||||
function (angular, _, dateMath) {
|
function (angular, _, dateMath) {
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
/** @ngInject */
|
/** @ngInject */
|
||||||
function OpenTSDBDatasource(instanceSettings, $q, backendSrv, templateSrv) {
|
function OpenTsDatasource(instanceSettings, $q, backendSrv, templateSrv) {
|
||||||
this.type = 'opentsdb';
|
this.type = 'opentsdb';
|
||||||
this.url = instanceSettings.url;
|
this.url = instanceSettings.url;
|
||||||
this.name = instanceSettings.name;
|
this.name = instanceSettings.name;
|
||||||
@ -73,13 +72,13 @@ function (angular, _, dateMath) {
|
|||||||
url: this.url + '/api/query',
|
url: this.url + '/api/query',
|
||||||
data: reqBody
|
data: reqBody
|
||||||
};
|
};
|
||||||
|
|
||||||
if (this.basicAuth || this.withCredentials) {
|
if (this.basicAuth || this.withCredentials) {
|
||||||
options.withCredentials = true;
|
options.withCredentials = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.basicAuth) {
|
if (this.basicAuth) {
|
||||||
options.headers = {
|
options.headers = {"Authorization": this.basicAuth};
|
||||||
"Authorization": this.basicAuth
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// In case the backend is 3rd-party hosted and does not suport OPTIONS, urlencoded requests
|
// In case the backend is 3rd-party hosted and does not suport OPTIONS, urlencoded requests
|
||||||
@ -325,5 +324,7 @@ function (angular, _, dateMath) {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return OpenTSDBDatasource;
|
return {
|
||||||
|
OpenTsDatasource: OpenTsDatasource
|
||||||
|
};
|
||||||
});
|
});
|
||||||
|
@ -1,23 +0,0 @@
|
|||||||
define([
|
|
||||||
'./datasource',
|
|
||||||
],
|
|
||||||
function (OpenTsDatasource) {
|
|
||||||
'use strict';
|
|
||||||
|
|
||||||
function metricsQueryEditor() {
|
|
||||||
return {
|
|
||||||
controller: 'OpenTSDBQueryCtrl',
|
|
||||||
templateUrl: 'public/app/plugins/datasource/opentsdb/partials/query.editor.html',
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
function configView() {
|
|
||||||
return {templateUrl: 'public/app/plugins/datasource/opentsdb/partials/config.html'};
|
|
||||||
}
|
|
||||||
|
|
||||||
return {
|
|
||||||
Datasource: OpenTsDatasource,
|
|
||||||
metricsQueryEditor: metricsQueryEditor,
|
|
||||||
configView: configView,
|
|
||||||
};
|
|
||||||
});
|
|
13
public/app/plugins/datasource/opentsdb/module.ts
Normal file
13
public/app/plugins/datasource/opentsdb/module.ts
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
import {OpenTsDatasource} from './datasource';
|
||||||
|
import {OpenTsQueryCtrl} from './query_ctrl';
|
||||||
|
|
||||||
|
class OpenTsConfigCtrl {
|
||||||
|
static templateUrl = 'public/app/plugins/datasource/opentsdb/partials/config.html';
|
||||||
|
}
|
||||||
|
|
||||||
|
export {
|
||||||
|
OpenTsDatasource as Datasource,
|
||||||
|
OpenTsQueryCtrl as QueryCtrl,
|
||||||
|
OpenTsConfigCtrl as ConfigCtrl,
|
||||||
|
};
|
||||||
|
|
@ -1,2 +1,2 @@
|
|||||||
<datasource-http-settings></datasource-http-settings>
|
<datasource-http-settings current="ctrl.current"></datasource-http-settings>
|
||||||
|
|
||||||
|
@ -1,50 +1,13 @@
|
|||||||
<div class="tight-form">
|
<query-editor-row ctrl="ctrl">
|
||||||
<ul class="tight-form-list pull-right">
|
|
||||||
<li class="tight-form-item small" ng-show="target.datasource">
|
|
||||||
<em>{{target.datasource}}</em>
|
|
||||||
</li>
|
|
||||||
<li class="tight-form-item">
|
|
||||||
<div class="dropdown">
|
|
||||||
<a class="pointer dropdown-toggle" data-toggle="dropdown" tabindex="1">
|
|
||||||
<i class="fa fa-bars"></i>
|
|
||||||
</a>
|
|
||||||
<ul class="dropdown-menu pull-right" role="menu">
|
|
||||||
<li role="menuitem"><a tabindex="1" ng-click="panelCtrl.duplicateDataQuery(target)">Duplicate</a></li>
|
|
||||||
<li role="menuitem"><a tabindex="1" ng-click="panelCtrl.moveDataQuery($index, $index-1)">Move up</a></li>
|
|
||||||
<li role="menuitem"><a tabindex="1" ng-click="panelCtrl.moveDataQuery($index, $index+1)">Move down</a></li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
</li>
|
|
||||||
<li class="tight-form-item last">
|
|
||||||
<a class="pointer" tabindex="1" ng-click="panelCtrl.removeDataQuery(target)">
|
|
||||||
<i class="fa fa-remove"></i>
|
|
||||||
</a>
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
|
|
||||||
<ul class="tight-form-list">
|
|
||||||
<li class="tight-form-item" style="min-width: 15px; text-align: center">
|
|
||||||
{{target.refId}}
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
<a class="tight-form-item"
|
|
||||||
ng-click="target.hide = !target.hide; panelCtrl.refresh();"
|
|
||||||
role="menuitem">
|
|
||||||
<i class="fa fa-eye"></i>
|
|
||||||
</a>
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
|
|
||||||
<ul class="tight-form-list" role="menu">
|
|
||||||
<li class="tight-form-item query-keyword" style="width: 100px">
|
<li class="tight-form-item query-keyword" style="width: 100px">
|
||||||
Metric
|
Metric
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
<input type="text" class="input-large tight-form-input" ng-model="target.metric"
|
<input type="text" class="input-large tight-form-input" ng-model="ctrl.target.metric"
|
||||||
spellcheck='false' bs-typeahead="suggestMetrics" placeholder="metric name" data-min-length=0 data-items=100
|
spellcheck='false' bs-typeahead="ctrl.suggestMetrics" placeholder="metric name" data-min-length=0 data-items=100
|
||||||
ng-blur="targetBlur()">
|
ng-blur="ctrl.targetBlur()">
|
||||||
</input>
|
</input>
|
||||||
<a bs-tooltip="target.errors.metric" style="color: rgb(229, 189, 28)" ng-show="target.errors.metric">
|
<a bs-tooltip="ctrl.errors.metric" style="color: rgb(229, 189, 28)" ng-show="ctrl.errors.metric">
|
||||||
<i class="fa fa-warning"></i>
|
<i class="fa fa-warning"></i>
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
@ -52,11 +15,11 @@
|
|||||||
Aggregator
|
Aggregator
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
<select ng-model="target.aggregator" class="tight-form-input input-small"
|
<select ng-model="ctrl.target.aggregator" class="tight-form-input input-small"
|
||||||
ng-options="agg for agg in aggregators"
|
ng-options="agg for agg in ctrl.aggregators"
|
||||||
ng-change="targetBlur()">
|
ng-change="ctrl.targetBlur()">
|
||||||
</select>
|
</select>
|
||||||
<a bs-tooltip="target.errors.aggregator" style="color: rgb(229, 189, 28)" ng-show="target.errors.aggregator">
|
<a bs-tooltip="ctrl.errors.aggregator" style="color: rgb(229, 189, 28)" ng-show="ctrl.errors.aggregator">
|
||||||
<i class="fa fa-warning"></i>
|
<i class="fa fa-warning"></i>
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
@ -67,16 +30,13 @@
|
|||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
<input type="text" class="tight-form-input input-large"
|
<input type="text" class="tight-form-input input-large"
|
||||||
ng-model="target.alias"
|
ng-model="ctrl.target.alias"
|
||||||
spellcheck='false'
|
spellcheck='false'
|
||||||
placeholder="series alias"
|
placeholder="series alias"
|
||||||
data-min-length=0 data-items=100
|
data-min-length=0 data-items=100
|
||||||
ng-blur="targetBlur()"></input>
|
ng-blur="ctrl.targetBlur()"></input>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</query-editor-row>
|
||||||
|
|
||||||
<div class="clearfix"></div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="tight-form">
|
<div class="tight-form">
|
||||||
<ul class="tight-form-list" role="menu">
|
<ul class="tight-form-list" role="menu">
|
||||||
@ -86,9 +46,9 @@
|
|||||||
|
|
||||||
<li>
|
<li>
|
||||||
<input type="text" class="input-large tight-form-input"
|
<input type="text" class="input-large tight-form-input"
|
||||||
ng-model="target.downsampleInterval"
|
ng-model="ctrl.target.downsampleInterval"
|
||||||
ng-model-onblur
|
ng-model-onblur
|
||||||
ng-change="targetBlur()"
|
ng-change="ctrl.targetBlur()"
|
||||||
placeholder="interval (empty = auto)"></input>
|
placeholder="interval (empty = auto)"></input>
|
||||||
</li>
|
</li>
|
||||||
|
|
||||||
@ -97,26 +57,26 @@
|
|||||||
</li>
|
</li>
|
||||||
|
|
||||||
<li>
|
<li>
|
||||||
<select ng-model="target.downsampleAggregator" class="tight-form-input input-small"
|
<select ng-model="ctrl.target.downsampleAggregator" class="tight-form-input input-small"
|
||||||
ng-options="agg for agg in aggregators"
|
ng-options="agg for agg in ctrl.aggregators"
|
||||||
ng-change="targetBlur()">
|
ng-change="ctrl.targetBlur()">
|
||||||
</select>
|
</select>
|
||||||
</li>
|
</li>
|
||||||
|
|
||||||
<li class="tight-form-item query-keyword">
|
<li class="tight-form-item query-keyword" style="width: 59px">
|
||||||
Fill policy
|
Fill
|
||||||
<tip>Available since OpenTSDB 2.2</tip>
|
<tip>Available since OpenTSDB 2.2</tip>
|
||||||
</li>
|
</li>
|
||||||
|
|
||||||
<li>
|
<li>
|
||||||
<select ng-model="target.downsampleFillPolicy" class="tight-form-input input-small"
|
<select ng-model="ctrl.target.downsampleFillPolicy" class="tight-form-input input-small"
|
||||||
ng-options="agg for agg in fillPolicies"
|
ng-options="agg for agg in ctrl.fillPolicies"
|
||||||
ng-change="targetBlur()">
|
ng-change="ctrl.targetBlur()">
|
||||||
</select>
|
</select>
|
||||||
</li>
|
</li>
|
||||||
|
|
||||||
<li class="tight-form-item query-keyword">
|
<li class="tight-form-item query-keyword">
|
||||||
Disable downsampling <editor-checkbox text="" model="target.disableDownsampling" change="targetBlur()"></editor-checkbox>
|
Disable downsampling <editor-checkbox text="" model="ctrl.target.disableDownsampling" change="ctrl.targetBlur()"></editor-checkbox>
|
||||||
</li>
|
</li>
|
||||||
|
|
||||||
</ul>
|
</ul>
|
||||||
@ -128,35 +88,35 @@
|
|||||||
<li class="tight-form-item tight-form-align query-keyword" style="width: 100px">
|
<li class="tight-form-item tight-form-align query-keyword" style="width: 100px">
|
||||||
Tags
|
Tags
|
||||||
</li>
|
</li>
|
||||||
<li ng-repeat="(key, value) in target.tags track by $index" class="tight-form-item">
|
<li ng-repeat="(key, value) in ctrl.target.tags track by $index" class="tight-form-item">
|
||||||
{{key}} = {{value}}
|
{{key}} = {{value}}
|
||||||
<a ng-click="editTag(key, value)">
|
<a ng-click="ctrl.editTag(key, value)">
|
||||||
<i class="fa fa-pencil"></i>
|
<i class="fa fa-pencil"></i>
|
||||||
</a>
|
</a>
|
||||||
<a ng-click="removeTag(key)">
|
<a ng-click="ctrl.removeTag(key)">
|
||||||
<i class="fa fa-remove"></i>
|
<i class="fa fa-remove"></i>
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
|
|
||||||
<li class="tight-form-item query-keyword" ng-hide="addTagMode">
|
<li class="tight-form-item query-keyword" ng-hide="ctrl.addTagMode">
|
||||||
<a ng-click="addTag()">
|
<a ng-click="ctrl.addTag()">
|
||||||
<i class="fa fa-plus"></i>
|
<i class="fa fa-plus"></i>
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
|
|
||||||
<li ng-show="addTagMode">
|
<li ng-show="ctrl.addTagMode">
|
||||||
<input type="text" class="input-small tight-form-input" spellcheck='false'
|
<input type="text" class="input-small tight-form-input" spellcheck='false'
|
||||||
bs-typeahead="suggestTagKeys" data-min-length=0 data-items=100
|
bs-typeahead="ctrl.suggestTagKeys" data-min-length=0 data-items=100
|
||||||
ng-model="target.currentTagKey" placeholder="key"></input>
|
ng-model="ctrl.target.currentTagKey" placeholder="key"></input>
|
||||||
|
|
||||||
<input type="text" class="input-small tight-form-input"
|
<input type="text" class="input-small tight-form-input"
|
||||||
spellcheck='false' bs-typeahead="suggestTagValues"
|
spellcheck='false' bs-typeahead="ctrl.suggestTagValues"
|
||||||
data-min-length=0 data-items=100 ng-model="target.currentTagValue" placeholder="value">
|
data-min-length=0 data-items=100 ng-model="ctrl.target.currentTagValue" placeholder="value">
|
||||||
</input>
|
</input>
|
||||||
<a ng-click="addTag()">
|
<a ng-click="ctrl.addTag()">
|
||||||
add tag
|
add tag
|
||||||
</a>
|
</a>
|
||||||
<a bs-tooltip="target.errors.tags"
|
<a bs-tooltip="ctrl.errors.tags"
|
||||||
style="color: rgb(229, 189, 28)"
|
style="color: rgb(229, 189, 28)"
|
||||||
ng-show="target.errors.tags">
|
ng-show="target.errors.tags">
|
||||||
<i class="fa fa-warning"></i>
|
<i class="fa fa-warning"></i>
|
||||||
@ -169,31 +129,31 @@
|
|||||||
<div class="tight-form">
|
<div class="tight-form">
|
||||||
<ul class="tight-form-list" role="menu">
|
<ul class="tight-form-list" role="menu">
|
||||||
<li class="tight-form-item tight-form-align query-keyword" style="width: 100px">
|
<li class="tight-form-item tight-form-align query-keyword" style="width: 100px">
|
||||||
Rate <editor-checkbox text="" model="target.shouldComputeRate" change="targetBlur()"></editor-checkbox>
|
Rate <editor-checkbox text="" model="ctrl.target.shouldComputeRate" change="ctrl.targetBlur()"></editor-checkbox>
|
||||||
</li>
|
</li>
|
||||||
|
|
||||||
<li class="tight-form-item query-keyword" ng-hide="!target.shouldComputeRate">
|
<li class="tight-form-item query-keyword" ng-hide="!ctrl.target.shouldComputeRate">
|
||||||
Counter <editor-checkbox text="" model="target.isCounter" change="targetBlur()"></editor-checkbox>
|
Counter <editor-checkbox text="" model="ctrl.target.isCounter" change="ctrl.targetBlur()"></editor-checkbox>
|
||||||
</li>
|
</li>
|
||||||
|
|
||||||
<li class="tight-form-item query-keyword" ng-hide="!target.isCounter || !target.shouldComputeRate">
|
<li class="tight-form-item query-keyword" ng-hide="!ctrl.target.isCounter || !ctrl.target.shouldComputeRate">
|
||||||
Counter Max:
|
Counter Max:
|
||||||
</li>
|
</li>
|
||||||
|
|
||||||
<li ng-hide="!target.isCounter || !target.shouldComputeRate">
|
<li ng-hide="!ctrl.target.isCounter || !ctrl.target.shouldComputeRate">
|
||||||
<input type="text" class="tight-form-input input-small" ng-disabled="!target.shouldComputeRate"
|
<input type="text" class="tight-form-input input-small" ng-disabled="!ctrl.target.shouldComputeRate"
|
||||||
ng-model="target.counterMax" spellcheck='false'
|
ng-model="ctrl.target.counterMax" spellcheck='false'
|
||||||
placeholder="max value" ng-model-onblur
|
placeholder="max value" ng-model-onblur
|
||||||
ng-blur="targetBlur()"></input>
|
ng-blur="ctrl.targetBlur()"></input>
|
||||||
</li>
|
</li>
|
||||||
<li class="tight-form-item query-keyword" ng-hide="!target.isCounter || !target.shouldComputeRate">
|
<li class="tight-form-item query-keyword" ng-hide="!ctrl.target.isCounter || !ctrl.target.shouldComputeRate">
|
||||||
Reset Value:
|
Reset Value:
|
||||||
</li>
|
</li>
|
||||||
<li ng-hide="!target.isCounter || !target.shouldComputeRate">
|
<li ng-hide="!ctrl.target.isCounter || !ctrl.target.shouldComputeRate">
|
||||||
<input type="text" class="tight-form-input input-small" ng-disabled="!target.shouldComputeRate"
|
<input type="text" class="tight-form-input input-small" ng-disabled="!ctrl.target.shouldComputeRate"
|
||||||
ng-model="target.counterResetValue" spellcheck='false'
|
ng-model="ctrl.target.counterResetValue" spellcheck='false'
|
||||||
placeholder="reset value" ng-model-onblur
|
placeholder="reset value" ng-model-onblur
|
||||||
ng-blur="targetBlur()"></input>
|
ng-blur="ctrl.targetBlur()"></input>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
|
@ -1,127 +0,0 @@
|
|||||||
define([
|
|
||||||
'angular',
|
|
||||||
'lodash',
|
|
||||||
'app/core/utils/kbn'
|
|
||||||
],
|
|
||||||
function (angular, _, kbn) {
|
|
||||||
'use strict';
|
|
||||||
|
|
||||||
var module = angular.module('grafana.controllers');
|
|
||||||
|
|
||||||
module.controller('OpenTSDBQueryCtrl', function($scope) {
|
|
||||||
$scope.panelCtrl = $scope.ctrl;
|
|
||||||
|
|
||||||
$scope.init = function() {
|
|
||||||
$scope.target.errors = validateTarget($scope.target);
|
|
||||||
$scope.aggregators = ['avg', 'sum', 'min', 'max', 'dev', 'zimsum', 'mimmin', 'mimmax'];
|
|
||||||
$scope.fillPolicies = ['none', 'nan', 'null', 'zero'];
|
|
||||||
|
|
||||||
if (!$scope.target.aggregator) {
|
|
||||||
$scope.target.aggregator = 'sum';
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!$scope.target.downsampleAggregator) {
|
|
||||||
$scope.target.downsampleAggregator = 'avg';
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!$scope.target.downsampleFillPolicy) {
|
|
||||||
$scope.target.downsampleFillPolicy = 'none';
|
|
||||||
}
|
|
||||||
|
|
||||||
$scope.datasource.getAggregators().then(function(aggs) {
|
|
||||||
$scope.aggregators = aggs;
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
$scope.targetBlur = function() {
|
|
||||||
$scope.target.errors = validateTarget($scope.target);
|
|
||||||
|
|
||||||
// this does not work so good
|
|
||||||
if (!_.isEqual($scope.oldTarget, $scope.target) && _.isEmpty($scope.target.errors)) {
|
|
||||||
$scope.oldTarget = angular.copy($scope.target);
|
|
||||||
$scope.get_data();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
$scope.getTextValues = function(metricFindResult) {
|
|
||||||
return _.map(metricFindResult, function(value) { return value.text; });
|
|
||||||
};
|
|
||||||
|
|
||||||
$scope.suggestMetrics = function(query, callback) {
|
|
||||||
$scope.datasource.metricFindQuery('metrics(' + query + ')')
|
|
||||||
.then($scope.getTextValues)
|
|
||||||
.then(callback);
|
|
||||||
};
|
|
||||||
|
|
||||||
$scope.suggestTagKeys = function(query, callback) {
|
|
||||||
$scope.datasource.metricFindQuery('suggest_tagk(' + query + ')')
|
|
||||||
.then($scope.getTextValues)
|
|
||||||
.then(callback);
|
|
||||||
};
|
|
||||||
|
|
||||||
$scope.suggestTagValues = function(query, callback) {
|
|
||||||
$scope.datasource.metricFindQuery('suggest_tagv(' + query + ')')
|
|
||||||
.then($scope.getTextValues)
|
|
||||||
.then(callback);
|
|
||||||
};
|
|
||||||
|
|
||||||
$scope.addTag = function() {
|
|
||||||
if (!$scope.addTagMode) {
|
|
||||||
$scope.addTagMode = true;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!$scope.target.tags) {
|
|
||||||
$scope.target.tags = {};
|
|
||||||
}
|
|
||||||
|
|
||||||
$scope.target.errors = validateTarget($scope.target);
|
|
||||||
|
|
||||||
if (!$scope.target.errors.tags) {
|
|
||||||
$scope.target.tags[$scope.target.currentTagKey] = $scope.target.currentTagValue;
|
|
||||||
$scope.target.currentTagKey = '';
|
|
||||||
$scope.target.currentTagValue = '';
|
|
||||||
$scope.targetBlur();
|
|
||||||
}
|
|
||||||
|
|
||||||
$scope.addTagMode = false;
|
|
||||||
};
|
|
||||||
|
|
||||||
$scope.removeTag = function(key) {
|
|
||||||
delete $scope.target.tags[key];
|
|
||||||
$scope.targetBlur();
|
|
||||||
};
|
|
||||||
|
|
||||||
$scope.editTag = function(key, value) {
|
|
||||||
$scope.removeTag(key);
|
|
||||||
$scope.target.currentTagKey = key;
|
|
||||||
$scope.target.currentTagValue = value;
|
|
||||||
$scope.addTag();
|
|
||||||
};
|
|
||||||
|
|
||||||
function validateTarget(target) {
|
|
||||||
var errs = {};
|
|
||||||
|
|
||||||
if (target.shouldDownsample) {
|
|
||||||
try {
|
|
||||||
if (target.downsampleInterval) {
|
|
||||||
kbn.describe_interval(target.downsampleInterval);
|
|
||||||
} else {
|
|
||||||
errs.downsampleInterval = "You must supply a downsample interval (e.g. '1m' or '1h').";
|
|
||||||
}
|
|
||||||
} catch(err) {
|
|
||||||
errs.downsampleInterval = err.message;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (target.tags && _.has(target.tags, target.currentTagKey)) {
|
|
||||||
errs.tags = "Duplicate tag key '" + target.currentTagKey + "'.";
|
|
||||||
}
|
|
||||||
|
|
||||||
return errs;
|
|
||||||
}
|
|
||||||
|
|
||||||
$scope.init();
|
|
||||||
});
|
|
||||||
|
|
||||||
});
|
|
128
public/app/plugins/datasource/opentsdb/query_ctrl.ts
Normal file
128
public/app/plugins/datasource/opentsdb/query_ctrl.ts
Normal file
@ -0,0 +1,128 @@
|
|||||||
|
///<reference path="../../../headers/common.d.ts" />
|
||||||
|
|
||||||
|
import _ from 'lodash';
|
||||||
|
import kbn from 'app/core/utils/kbn';
|
||||||
|
import {QueryCtrl} from 'app/features/panel/panel';
|
||||||
|
|
||||||
|
export class OpenTsQueryCtrl extends QueryCtrl {
|
||||||
|
static templateUrl = 'public/app/plugins/datasource/opentsdb/partials/query.editor.html';
|
||||||
|
aggregators: any;
|
||||||
|
fillPolicies: any;
|
||||||
|
aggregator: any;
|
||||||
|
downsampleInterval: any;
|
||||||
|
downsampleAggregator: any;
|
||||||
|
downsampleFillPolicy: any;
|
||||||
|
errors: any;
|
||||||
|
suggestMetrics: any;
|
||||||
|
suggestTagKeys: any;
|
||||||
|
suggestTagValues: any;
|
||||||
|
addTagMode: boolean;
|
||||||
|
|
||||||
|
constructor($scope, $injector) {
|
||||||
|
super($scope, $injector);
|
||||||
|
|
||||||
|
this.errors = this.validateTarget();
|
||||||
|
this.aggregators = ['avg', 'sum', 'min', 'max', 'dev', 'zimsum', 'mimmin', 'mimmax'];
|
||||||
|
this.fillPolicies = ['none', 'nan', 'null', 'zero'];
|
||||||
|
|
||||||
|
if (!this.target.aggregator) {
|
||||||
|
this.target.aggregator = 'sum';
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!this.target.downsampleAggregator) {
|
||||||
|
this.target.downsampleAggregator = 'avg';
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!this.target.downsampleFillPolicy) {
|
||||||
|
this.target.downsampleFillPolicy = 'none';
|
||||||
|
}
|
||||||
|
|
||||||
|
this.datasource.getAggregators().then(function(aggs) {
|
||||||
|
this.aggregators = aggs;
|
||||||
|
});
|
||||||
|
|
||||||
|
// needs to be defined here as it is called from typeahead
|
||||||
|
this.suggestMetrics = (query, callback) => {
|
||||||
|
this.datasource.metricFindQuery('metrics(' + query + ')')
|
||||||
|
.then(this.getTextValues)
|
||||||
|
.then(callback);
|
||||||
|
};
|
||||||
|
|
||||||
|
this.suggestTagKeys = (query, callback) => {
|
||||||
|
this.datasource.metricFindQuery('suggest_tagk(' + query + ')')
|
||||||
|
.then(this.getTextValues)
|
||||||
|
.then(callback);
|
||||||
|
};
|
||||||
|
|
||||||
|
this.suggestTagValues = (query, callback) => {
|
||||||
|
this.datasource.metricFindQuery('suggest_tagv(' + query + ')')
|
||||||
|
.then(this.getTextValues)
|
||||||
|
.then(callback);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
targetBlur() {
|
||||||
|
this.errors = this.validateTarget();
|
||||||
|
this.refresh();
|
||||||
|
}
|
||||||
|
|
||||||
|
getTextValues(metricFindResult) {
|
||||||
|
return _.map(metricFindResult, function(value) { return value.text; });
|
||||||
|
}
|
||||||
|
|
||||||
|
addTag() {
|
||||||
|
if (!this.addTagMode) {
|
||||||
|
this.addTagMode = true;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!this.target.tags) {
|
||||||
|
this.target.tags = {};
|
||||||
|
}
|
||||||
|
|
||||||
|
this.errors = this.validateTarget();
|
||||||
|
|
||||||
|
if (!this.errors.tags) {
|
||||||
|
this.target.tags[this.target.currentTagKey] = this.target.currentTagValue;
|
||||||
|
this.target.currentTagKey = '';
|
||||||
|
this.target.currentTagValue = '';
|
||||||
|
this.targetBlur();
|
||||||
|
}
|
||||||
|
|
||||||
|
this.addTagMode = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
removeTag(key) {
|
||||||
|
delete this.target.tags[key];
|
||||||
|
this.targetBlur();
|
||||||
|
}
|
||||||
|
|
||||||
|
editTag(key, value) {
|
||||||
|
this.removeTag(key);
|
||||||
|
this.target.currentTagKey = key;
|
||||||
|
this.target.currentTagValue = value;
|
||||||
|
this.addTag();
|
||||||
|
}
|
||||||
|
|
||||||
|
validateTarget() {
|
||||||
|
var errs: any = {};
|
||||||
|
|
||||||
|
if (this.target.shouldDownsample) {
|
||||||
|
try {
|
||||||
|
if (this.target.downsampleInterval) {
|
||||||
|
kbn.describe_interval(this.target.downsampleInterval);
|
||||||
|
} else {
|
||||||
|
errs.downsampleInterval = "You must supply a downsample interval (e.g. '1m' or '1h').";
|
||||||
|
}
|
||||||
|
} catch (err) {
|
||||||
|
errs.downsampleInterval = err.message;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.target.tags && _.has(this.target.tags, this.target.currentTagKey)) {
|
||||||
|
errs.tags = "Duplicate tag key '" + this.target.currentTagKey + "'.";
|
||||||
|
}
|
||||||
|
|
||||||
|
return errs;
|
||||||
|
}
|
||||||
|
}
|
@ -1,6 +1,6 @@
|
|||||||
import {describe, beforeEach, it, sinon, expect, angularMocks} from 'test/lib/common';
|
import {describe, beforeEach, it, sinon, expect, angularMocks} from 'test/lib/common';
|
||||||
import helpers from 'test/specs/helpers';
|
import helpers from 'test/specs/helpers';
|
||||||
import Datasource from "../datasource";
|
import {OpenTsDatasource} from "../datasource";
|
||||||
|
|
||||||
describe('opentsdb', function() {
|
describe('opentsdb', function() {
|
||||||
var ctx = new helpers.ServiceTestContext();
|
var ctx = new helpers.ServiceTestContext();
|
||||||
@ -14,7 +14,7 @@ describe('opentsdb', function() {
|
|||||||
ctx.$q = $q;
|
ctx.$q = $q;
|
||||||
ctx.$httpBackend = $httpBackend;
|
ctx.$httpBackend = $httpBackend;
|
||||||
ctx.$rootScope = $rootScope;
|
ctx.$rootScope = $rootScope;
|
||||||
ctx.ds = $injector.instantiate(Datasource, {instanceSettings: instanceSettings});
|
ctx.ds = $injector.instantiate(OpenTsDatasource, {instanceSettings: instanceSettings});
|
||||||
}));
|
}));
|
||||||
|
|
||||||
describe('When performing metricFindQuery', function() {
|
describe('When performing metricFindQuery', function() {
|
||||||
|
Loading…
Reference in New Issue
Block a user