mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
Progress on influxdb and templated queries/variables, #613
This commit is contained in:
parent
39c068bd53
commit
2dc4434a49
@ -652,5 +652,14 @@ function($, _, moment) {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
kbn.stringToJsRegex = function(str) {
|
||||||
|
if (str[0] !== '/') {
|
||||||
|
return new RegExp(str);
|
||||||
|
}
|
||||||
|
|
||||||
|
var match = str.match(new RegExp('^/(.*?)/(g?i?m?y?)$'));
|
||||||
|
return new RegExp(match[1], match[2]);
|
||||||
|
};
|
||||||
|
|
||||||
return kbn;
|
return kbn;
|
||||||
});
|
});
|
||||||
|
@ -15,8 +15,7 @@ function (_, kbn) {
|
|||||||
if (!aliasOrRegex) { return false; }
|
if (!aliasOrRegex) { return false; }
|
||||||
|
|
||||||
if (aliasOrRegex[0] === '/') {
|
if (aliasOrRegex[0] === '/') {
|
||||||
var match = aliasOrRegex.match(new RegExp('^/(.*?)/(g?i?m?y?)$'));
|
var regex = kbn.stringToJsRegex(aliasOrRegex);
|
||||||
var regex = new RegExp(match[1], match[2]);
|
|
||||||
return seriesAlias.match(regex) != null;
|
return seriesAlias.match(regex) != null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -7,7 +7,7 @@ function (angular, _) {
|
|||||||
|
|
||||||
var module = angular.module('grafana.controllers');
|
var module = angular.module('grafana.controllers');
|
||||||
|
|
||||||
module.controller('TemplateEditorCtrl', function($scope, datasourceSrv, templateSrv, templateValuesSrv) {
|
module.controller('TemplateEditorCtrl', function($scope, datasourceSrv, templateSrv, templateValuesSrv, alertSrv) {
|
||||||
|
|
||||||
var replacementDefaults = {
|
var replacementDefaults = {
|
||||||
type: 'query',
|
type: 'query',
|
||||||
@ -38,7 +38,10 @@ function (angular, _) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
$scope.runQuery = function() {
|
$scope.runQuery = function() {
|
||||||
templateValuesSrv.updateOptions($scope.current);
|
return templateValuesSrv.updateOptions($scope.current).then(function() {
|
||||||
|
}, function(err) {
|
||||||
|
alertSrv.set('Templating', 'Failed to run query for variable values: ' + err.message, 'error');
|
||||||
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
$scope.edit = function(variable) {
|
$scope.edit = function(variable) {
|
||||||
@ -54,9 +57,10 @@ function (angular, _) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
$scope.update = function() {
|
$scope.update = function() {
|
||||||
templateValuesSrv.updateOptions($scope.current);
|
$scope.runQuery().then(function() {
|
||||||
$scope.reset();
|
$scope.reset();
|
||||||
$scope.editor.index = 0;
|
$scope.editor.index = 0;
|
||||||
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
$scope.reset = function() {
|
$scope.reset = function() {
|
||||||
@ -68,9 +72,6 @@ function (angular, _) {
|
|||||||
if ($scope.current.type === 'time period') {
|
if ($scope.current.type === 'time period') {
|
||||||
$scope.current.query = '1m,10m,30m,1h,6h,12h,1d,7d,14d,30d';
|
$scope.current.query = '1m,10m,30m,1h,6h,12h,1d,7d,14d,30d';
|
||||||
}
|
}
|
||||||
else {
|
|
||||||
$scope.current.query = '';
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
$scope.removeVariable = function(variable) {
|
$scope.removeVariable = function(variable) {
|
||||||
|
@ -113,7 +113,7 @@
|
|||||||
<div class="editor-option">
|
<div class="editor-option">
|
||||||
<div class="editor-row">
|
<div class="editor-row">
|
||||||
<div class="editor-option" >
|
<div class="editor-option" >
|
||||||
<label class="small">Variable values (first 20)</label>
|
<label class="small">Variable values (showing 20/{{current.options.length}})</label>
|
||||||
<ul class="grafana-options-list">
|
<ul class="grafana-options-list">
|
||||||
<li ng-repeat="option in current.options | limitTo: 20">
|
<li ng-repeat="option in current.options | limitTo: 20">
|
||||||
{{option.text}}
|
{{option.text}}
|
||||||
|
@ -214,6 +214,7 @@ function (angular, $, kbn, _, moment) {
|
|||||||
for (i = 0 ; i < this.templating.list.length; i++) {
|
for (i = 0 ; i < this.templating.list.length; i++) {
|
||||||
var variable = this.templating.list[i];
|
var variable = this.templating.list[i];
|
||||||
if (variable.datasource === void 0) { variable.datasource = null; }
|
if (variable.datasource === void 0) { variable.datasource = null; }
|
||||||
|
if (variable.type === 'filter') { variable.type = 'query'; }
|
||||||
if (variable.type === void 0) { variable.type = 'query'; }
|
if (variable.type === void 0) { variable.type = 'query'; }
|
||||||
if (variable.allFormat === void 0) { variable.allFormat = 'Glob'; }
|
if (variable.allFormat === void 0) { variable.allFormat = 'Glob'; }
|
||||||
}
|
}
|
||||||
|
@ -161,7 +161,7 @@ function (angular, _, kbn, InfluxSeries) {
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
InfluxDatasource.prototype.metricFindQuery = function (filterSrv, query) {
|
InfluxDatasource.prototype.metricFindQuery = function (query) {
|
||||||
var interpolated;
|
var interpolated;
|
||||||
try {
|
try {
|
||||||
interpolated = templateSrv.replace(query);
|
interpolated = templateSrv.replace(query);
|
||||||
|
@ -2,9 +2,8 @@ define([
|
|||||||
'angular',
|
'angular',
|
||||||
'lodash',
|
'lodash',
|
||||||
'kbn',
|
'kbn',
|
||||||
'store'
|
|
||||||
],
|
],
|
||||||
function (angular, _) {
|
function (angular, _, kbn) {
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
var module = angular.module('grafana.services');
|
var module = angular.module('grafana.services');
|
||||||
@ -30,7 +29,7 @@ function (angular, _) {
|
|||||||
|
|
||||||
templateSrv.updateTemplateData();
|
templateSrv.updateTemplateData();
|
||||||
|
|
||||||
return this.applyFilterToOtherFilters(variable)
|
return this.updateOptionsInChildVariables(variable)
|
||||||
.then(function() {
|
.then(function() {
|
||||||
if (!recursive) {
|
if (!recursive) {
|
||||||
$rootScope.$broadcast('refresh');
|
$rootScope.$broadcast('refresh');
|
||||||
@ -38,7 +37,7 @@ function (angular, _) {
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
this.applyFilterToOtherFilters = function(updatedVariable) {
|
this.updateOptionsInChildVariables = function(updatedVariable) {
|
||||||
var promises = _.map(self.variables, function(otherVariable) {
|
var promises = _.map(self.variables, function(otherVariable) {
|
||||||
if (otherVariable === updatedVariable) {
|
if (otherVariable === updatedVariable) {
|
||||||
return;
|
return;
|
||||||
@ -63,9 +62,8 @@ function (angular, _) {
|
|||||||
var datasource = datasourceSrv.get(variable.datasource);
|
var datasource = datasourceSrv.get(variable.datasource);
|
||||||
return datasource.metricFindQuery(variable.query)
|
return datasource.metricFindQuery(variable.query)
|
||||||
.then(function (results) {
|
.then(function (results) {
|
||||||
variable.options = _.map(results, function(node) {
|
|
||||||
return { text: node.text, value: node.text };
|
variable.options = self.metricNamesToVariableValues(variable, results);
|
||||||
});
|
|
||||||
|
|
||||||
if (variable.includeAll) {
|
if (variable.includeAll) {
|
||||||
self.addAllOption(variable);
|
self.addAllOption(variable);
|
||||||
@ -84,6 +82,31 @@ function (angular, _) {
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
this.metricNamesToVariableValues = function(variable, metricNames) {
|
||||||
|
var regex, options, i, matches;
|
||||||
|
options = [];
|
||||||
|
|
||||||
|
if (variable.regex) {
|
||||||
|
regex = kbn.stringToJsRegex(variable.regex);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < metricNames.length; i++) {
|
||||||
|
var value = metricNames[i].text;
|
||||||
|
|
||||||
|
if (regex) {
|
||||||
|
matches = regex.exec(value);
|
||||||
|
if (!matches) { continue; }
|
||||||
|
if (matches.length > 1) {
|
||||||
|
value = matches[1];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
options.push({text: value, value: value});
|
||||||
|
}
|
||||||
|
|
||||||
|
return options;
|
||||||
|
};
|
||||||
|
|
||||||
this.addAllOption = function(variable) {
|
this.addAllOption = function(variable) {
|
||||||
var allValue = '';
|
var allValue = '';
|
||||||
switch(variable.allFormat) {
|
switch(variable.allFormat) {
|
||||||
|
@ -8,26 +8,27 @@ define([
|
|||||||
describe('templateValuesSrv', function() {
|
describe('templateValuesSrv', function() {
|
||||||
var _templateValuesSrv;
|
var _templateValuesSrv;
|
||||||
var _dashboard;
|
var _dashboard;
|
||||||
|
var _datasourceSrv = {};
|
||||||
|
var _q;
|
||||||
|
var _rootScope;
|
||||||
|
|
||||||
beforeEach(module('grafana.services'));
|
beforeEach(module('grafana.services'));
|
||||||
beforeEach(module(function($provide) {
|
beforeEach(module(function($provide) {
|
||||||
$provide.value('datasourceSrv', {});
|
$provide.value('datasourceSrv', _datasourceSrv);
|
||||||
$provide.value('templateSrv', {
|
$provide.value('templateSrv', {
|
||||||
updateTemplateData: function() {}
|
updateTemplateData: function() {}
|
||||||
});
|
});
|
||||||
_dashboard = dashboardMock.create();
|
_dashboard = dashboardMock.create();
|
||||||
}));
|
}));
|
||||||
|
|
||||||
beforeEach(inject(function(templateValuesSrv) {
|
beforeEach(inject(function(templateValuesSrv, $rootScope, $q) {
|
||||||
_templateValuesSrv = templateValuesSrv;
|
_templateValuesSrv = templateValuesSrv;
|
||||||
|
_rootScope = $rootScope;
|
||||||
|
_q = $q;
|
||||||
}));
|
}));
|
||||||
|
|
||||||
describe('update time period variable options', function() {
|
describe('update time period variable options', function() {
|
||||||
var variable = {
|
var variable = { type: 'time period', query: 'auto,1s,2h,5h,1d', name: 'test' };
|
||||||
type: 'time period',
|
|
||||||
query: 'auto,1s,2h,5h,1d',
|
|
||||||
name: 'test'
|
|
||||||
};
|
|
||||||
|
|
||||||
beforeEach(function() {
|
beforeEach(function() {
|
||||||
_templateValuesSrv.updateOptions(variable);
|
_templateValuesSrv.updateOptions(variable);
|
||||||
@ -40,6 +41,128 @@ define([
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
function describeUpdateVariable(desc, fn) {
|
||||||
|
describe(desc, function() {
|
||||||
|
var ctx = {};
|
||||||
|
ctx.setup = function(setupFn) {
|
||||||
|
ctx.setupFn = setupFn;
|
||||||
|
};
|
||||||
|
|
||||||
|
beforeEach(function() {
|
||||||
|
ctx.setupFn();
|
||||||
|
var ds = {};
|
||||||
|
ds.metricFindQuery = sinon.stub().returns(_q.when(ctx.queryResult));
|
||||||
|
_datasourceSrv.get = sinon.stub().returns(ds);
|
||||||
|
|
||||||
|
_templateValuesSrv.updateOptions(ctx.variable);
|
||||||
|
_rootScope.$digest();
|
||||||
|
});
|
||||||
|
|
||||||
|
fn(ctx);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
describeUpdateVariable('time period variable ', function(ctx) {
|
||||||
|
ctx.setup(function() {
|
||||||
|
ctx.variable = { type: 'time period', query: 'auto,1s,2h,5h,1d', name: 'test' };
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should update options array', function() {
|
||||||
|
expect(ctx.variable.options.length).to.be(5);
|
||||||
|
expect(ctx.variable.options[1].text).to.be('1s');
|
||||||
|
expect(ctx.variable.options[1].value).to.be('1s');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describeUpdateVariable('basic query variable', function(ctx) {
|
||||||
|
ctx.setup(function() {
|
||||||
|
ctx.variable = { type: 'query', query: 'apps.*', name: 'test' };
|
||||||
|
ctx.queryResult = [{text: 'backend1'}, {text: 'backend2'}];
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should update options array', function() {
|
||||||
|
expect(ctx.variable.options.length).to.be(2);
|
||||||
|
expect(ctx.variable.options[0].text).to.be('backend1');
|
||||||
|
expect(ctx.variable.options[0].value).to.be('backend1');
|
||||||
|
expect(ctx.variable.options[1].value).to.be('backend2');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should select first option as value', function() {
|
||||||
|
expect(ctx.variable.current.value).to.be('backend1');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describeUpdateVariable('and existing value still exists in options', function(ctx) {
|
||||||
|
ctx.setup(function() {
|
||||||
|
ctx.variable = { type: 'query', query: 'apps.*', name: 'test' };
|
||||||
|
ctx.variable.current = { value: 'backend2'};
|
||||||
|
ctx.queryResult = [{text: 'backend1'}, {text: 'backend2'}];
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should keep variable value', function() {
|
||||||
|
expect(ctx.variable.current.value).to.be('backend2');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describeUpdateVariable('and regex pattern exists', function(ctx) {
|
||||||
|
ctx.setup(function() {
|
||||||
|
ctx.variable = { type: 'query', query: 'apps.*', name: 'test' };
|
||||||
|
ctx.variable.regex = '/apps.*(backend_[0-9]+)/';
|
||||||
|
ctx.queryResult = [{text: 'apps.backend.backend_01.counters.req'}, {text: 'apps.backend.backend_02.counters.req'}];
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should extract and use match group', function() {
|
||||||
|
expect(ctx.variable.options[0].value).to.be('backend_01');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describeUpdateVariable('and regex pattern exists and no match', function(ctx) {
|
||||||
|
ctx.setup(function() {
|
||||||
|
ctx.variable = { type: 'query', query: 'apps.*', name: 'test' };
|
||||||
|
ctx.variable.regex = '/apps.*(backendasd[0-9]+)/';
|
||||||
|
ctx.queryResult = [{text: 'apps.backend.backend_01.counters.req'}, {text: 'apps.backend.backend_02.counters.req'}];
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should not add non matching items', function() {
|
||||||
|
expect(ctx.variable.options.length).to.be(0);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describeUpdateVariable('regex pattern without slashes', function(ctx) {
|
||||||
|
ctx.setup(function() {
|
||||||
|
ctx.variable = { type: 'query', query: 'apps.*', name: 'test' };
|
||||||
|
ctx.variable.regex = 'backend_01';
|
||||||
|
ctx.queryResult = [{text: 'apps.backend.backend_01.counters.req'}, {text: 'apps.backend.backend_02.counters.req'}];
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return matches options', function() {
|
||||||
|
expect(ctx.variable.options.length).to.be(1);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describeUpdateVariable('and existing value still exists in options', function(ctx) {
|
||||||
|
ctx.setup(function() {
|
||||||
|
ctx.variable = { type: 'query', query: 'apps.*', name: 'test' };
|
||||||
|
ctx.variable.current = { value: 'backend2'};
|
||||||
|
ctx.queryResult = [{text: 'backend1'}, {text: 'backend2'}];
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should keep variable value', function() {
|
||||||
|
expect(ctx.variable.current.value).to.be('backend2');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describeUpdateVariable('with include All glob syntax', function(ctx) {
|
||||||
|
ctx.setup(function() {
|
||||||
|
ctx.variable = { type: 'query', query: 'apps.*', name: 'test', includeAll: true, allFormat: 'Glob' };
|
||||||
|
ctx.queryResult = [{text: 'backend1'}, {text: 'backend2'}, { text: 'backend3'}];
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should add All Glob option', function() {
|
||||||
|
expect(ctx.variable.options[0].value).to.be('{backend1,backend2,backend3}');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
});
|
});
|
||||||
|
Loading…
Reference in New Issue
Block a user