فهرست منبع

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
Mitsuhiro Tanda 7 سال پیش
والد
کامیت
c6fa0b90a7

+ 20 - 6
public/app/plugins/datasource/prometheus/completer.ts

@@ -5,32 +5,46 @@ export class PromCompleter {
   labelQueryCache: any;
   labelNameCache: any;
   labelValueCache: any;
+  templateVariableCompletions: any;
 
   identifierRegexps = [/\[/, /[a-zA-Z0-9_:]/];
 
-  constructor(private datasource: PrometheusDatasource) {
+  constructor(private datasource: PrometheusDatasource, private templateSrv) {
     this.labelQueryCache = {};
     this.labelNameCache = {};
     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) {
+    let wrappedCallback = (err, completions) => {
+      completions = completions.concat(this.templateVariableCompletions);
+      return callback(err, completions);
+    };
+
     let token = session.getTokenAt(pos.row, pos.column);
 
     switch (token.type) {
       case 'entity.name.tag.label-matcher':
         this.getCompletionsForLabelMatcherName(session, pos).then(completions => {
-          callback(null, completions);
+          wrappedCallback(null, completions);
         });
         return;
       case 'string.quoted.label-matcher':
         this.getCompletionsForLabelMatcherValue(session, pos).then(completions => {
-          callback(null, completions);
+          wrappedCallback(null, completions);
         });
         return;
       case 'entity.name.tag.label-list-matcher':
         this.getCompletionsForBinaryOperator(session, pos).then(completions => {
-          callback(null, completions);
+          wrappedCallback(null, completions);
         });
         return;
     }
@@ -59,14 +73,14 @@ export class PromCompleter {
         meta: 'range vector',
       });
 
-      callback(null, vectors);
+      wrappedCallback(null, vectors);
       return;
     }
 
     var query = prefix;
 
     return this.datasource.performSuggestQuery(query, true).then(metricNames => {
-      callback(
+      wrappedCallback(
         null,
         metricNames.map(name => {
           let value = name;

+ 3 - 0
public/app/plugins/datasource/prometheus/mode-prometheus.js

@@ -50,6 +50,9 @@ var PrometheusHighlightRules = function() {
       token : "keyword.control",
       regex : "by|without|on|ignoring|group_left|group_right",
       next  : "start-label-list-matcher"
+    }, {
+      token : "variable",
+      regex : "\\$[A-Za-z0-9_]+"
     }, {
       token : keywordMapper,
       regex : "[a-zA-Z_:][a-zA-Z0-9_:]*"

+ 1 - 1
public/app/plugins/datasource/prometheus/query_ctrl.ts

@@ -43,7 +43,7 @@ class PrometheusQueryCtrl extends QueryCtrl {
   }
 
   getCompleter(query) {
-    return new PromCompleter(this.datasource);
+    return new PromCompleter(this.datasource, this.templateSrv);
   }
 
   getDefaultFormat() {

+ 16 - 1
public/app/plugins/datasource/prometheus/specs/completer_specs.ts

@@ -1,9 +1,13 @@
 import { describe, it, sinon, expect } from 'test/lib/common';
+import helpers from 'test/specs/helpers';
 
 import { PromCompleter } from '../completer';
 import { PrometheusDatasource } from '../datasource';
 
 describe('Prometheus editor completer', function() {
+  var ctx = new helpers.ServiceTestContext();
+  beforeEach(ctx.providePhase(['templateSrv']));
+
   function getSessionStub(data) {
     return {
       getTokenAt: sinon.stub().returns(data.currentToken),
@@ -39,7 +43,18 @@ describe('Prometheus editor completer', function() {
       .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', () => {
     it('Should return range vectors', () => {