Commit c6fa0b90 by Mitsuhiro Tanda Committed by Alexander Zobnin

prometheus editor: variable autocomplete support (PR #9988)

* prometheus ace editor, template variable support

* minor fix

* support [[var]] notation

* don't remove last ] if token type is string

* Revert "don't remove last ] if token type is string"

This reverts commit bce5b2d56e7d01a63b756b2b989ee9796bcc6711.

* Revert "support [[var]] notation"

This reverts commit 10012f8ffe8cfbec62c37d7e99c7758c8a86ab6d.

* fix token type and regex
parent eef01e37
...@@ -5,32 +5,46 @@ export class PromCompleter { ...@@ -5,32 +5,46 @@ export class PromCompleter {
labelQueryCache: any; labelQueryCache: any;
labelNameCache: any; labelNameCache: any;
labelValueCache: any; labelValueCache: any;
templateVariableCompletions: any;
identifierRegexps = [/\[/, /[a-zA-Z0-9_:]/]; identifierRegexps = [/\[/, /[a-zA-Z0-9_:]/];
constructor(private datasource: PrometheusDatasource) { constructor(private datasource: PrometheusDatasource, private templateSrv) {
this.labelQueryCache = {}; this.labelQueryCache = {};
this.labelNameCache = {}; this.labelNameCache = {};
this.labelValueCache = {}; this.labelValueCache = {};
this.templateVariableCompletions = this.templateSrv.variables.map(variable => {
return {
caption: '$' + variable.name,
value: '$' + variable.name,
meta: 'variable',
score: Number.MAX_VALUE,
};
});
} }
getCompletions(editor, session, pos, prefix, callback) { getCompletions(editor, session, pos, prefix, callback) {
let wrappedCallback = (err, completions) => {
completions = completions.concat(this.templateVariableCompletions);
return callback(err, completions);
};
let token = session.getTokenAt(pos.row, pos.column); let token = session.getTokenAt(pos.row, pos.column);
switch (token.type) { switch (token.type) {
case 'entity.name.tag.label-matcher': case 'entity.name.tag.label-matcher':
this.getCompletionsForLabelMatcherName(session, pos).then(completions => { this.getCompletionsForLabelMatcherName(session, pos).then(completions => {
callback(null, completions); wrappedCallback(null, completions);
}); });
return; return;
case 'string.quoted.label-matcher': case 'string.quoted.label-matcher':
this.getCompletionsForLabelMatcherValue(session, pos).then(completions => { this.getCompletionsForLabelMatcherValue(session, pos).then(completions => {
callback(null, completions); wrappedCallback(null, completions);
}); });
return; return;
case 'entity.name.tag.label-list-matcher': case 'entity.name.tag.label-list-matcher':
this.getCompletionsForBinaryOperator(session, pos).then(completions => { this.getCompletionsForBinaryOperator(session, pos).then(completions => {
callback(null, completions); wrappedCallback(null, completions);
}); });
return; return;
} }
...@@ -59,14 +73,14 @@ export class PromCompleter { ...@@ -59,14 +73,14 @@ export class PromCompleter {
meta: 'range vector', meta: 'range vector',
}); });
callback(null, vectors); wrappedCallback(null, vectors);
return; return;
} }
var query = prefix; var query = prefix;
return this.datasource.performSuggestQuery(query, true).then(metricNames => { return this.datasource.performSuggestQuery(query, true).then(metricNames => {
callback( wrappedCallback(
null, null,
metricNames.map(name => { metricNames.map(name => {
let value = name; let value = name;
......
...@@ -51,6 +51,9 @@ var PrometheusHighlightRules = function() { ...@@ -51,6 +51,9 @@ var PrometheusHighlightRules = function() {
regex : "by|without|on|ignoring|group_left|group_right", regex : "by|without|on|ignoring|group_left|group_right",
next : "start-label-list-matcher" next : "start-label-list-matcher"
}, { }, {
token : "variable",
regex : "\\$[A-Za-z0-9_]+"
}, {
token : keywordMapper, token : keywordMapper,
regex : "[a-zA-Z_:][a-zA-Z0-9_:]*" regex : "[a-zA-Z_:][a-zA-Z0-9_:]*"
}, { }, {
......
...@@ -43,7 +43,7 @@ class PrometheusQueryCtrl extends QueryCtrl { ...@@ -43,7 +43,7 @@ class PrometheusQueryCtrl extends QueryCtrl {
} }
getCompleter(query) { getCompleter(query) {
return new PromCompleter(this.datasource); return new PromCompleter(this.datasource, this.templateSrv);
} }
getDefaultFormat() { getDefaultFormat() {
......
import { describe, it, sinon, expect } from 'test/lib/common'; import { describe, it, sinon, expect } from 'test/lib/common';
import helpers from 'test/specs/helpers';
import { PromCompleter } from '../completer'; import { PromCompleter } from '../completer';
import { PrometheusDatasource } from '../datasource'; import { PrometheusDatasource } from '../datasource';
describe('Prometheus editor completer', function() { describe('Prometheus editor completer', function() {
var ctx = new helpers.ServiceTestContext();
beforeEach(ctx.providePhase(['templateSrv']));
function getSessionStub(data) { function getSessionStub(data) {
return { return {
getTokenAt: sinon.stub().returns(data.currentToken), getTokenAt: sinon.stub().returns(data.currentToken),
...@@ -39,7 +43,18 @@ describe('Prometheus editor completer', function() { ...@@ -39,7 +43,18 @@ describe('Prometheus editor completer', function() {
.returns(Promise.resolve(['node_cpu'])), .returns(Promise.resolve(['node_cpu'])),
}; };
let completer = new PromCompleter(datasourceStub); let templateSrv = {
variables: [
{
name: 'var_name',
options: [
{ text: 'foo', value: 'foo', selected: false },
{ text: 'bar', value: 'bar', selected: true }
]
}
]
};
let completer = new PromCompleter(datasourceStub, templateSrv);
describe('When inside brackets', () => { describe('When inside brackets', () => {
it('Should return range vectors', () => { it('Should return range vectors', () => {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment