Просмотр исходного кода

Merge pull request #12597 from dehrax/7664-query-var

Interval and range in query template variable
David 7 лет назад
Родитель
Сommit
b09a7c5dd6

+ 18 - 2
public/app/plugins/datasource/prometheus/datasource.ts

@@ -196,13 +196,14 @@ export class PrometheusDatasource {
     var intervalFactor = target.intervalFactor || 1;
     // Adjust the interval to take into account any specified minimum and interval factor plus Prometheus limits
     var adjustedInterval = this.adjustInterval(interval, minInterval, range, intervalFactor);
-    var scopedVars = options.scopedVars;
+    var scopedVars = { ...options.scopedVars, ...this.getRangeScopedVars() };
     // If the interval was adjusted, make a shallow copy of scopedVars with updated interval vars
     if (interval !== adjustedInterval) {
       interval = adjustedInterval;
       scopedVars = Object.assign({}, options.scopedVars, {
         __interval: { text: interval + 's', value: interval + 's' },
         __interval_ms: { text: interval * 1000, value: interval * 1000 },
+        ...this.getRangeScopedVars(),
       });
     }
     query.step = interval;
@@ -285,11 +286,26 @@ export class PrometheusDatasource {
       return this.$q.when([]);
     }
 
-    let interpolated = this.templateSrv.replace(query, {}, this.interpolateQueryExpr);
+    let scopedVars = {
+      __interval: { text: this.interval, value: this.interval },
+      __interval_ms: { text: kbn.interval_to_ms(this.interval), value: kbn.interval_to_ms(this.interval) },
+      ...this.getRangeScopedVars(),
+    };
+    let interpolated = this.templateSrv.replace(query, scopedVars, this.interpolateQueryExpr);
     var metricFindQuery = new PrometheusMetricFindQuery(this, interpolated, this.timeSrv);
     return metricFindQuery.process();
   }
 
+  getRangeScopedVars() {
+    let range = this.timeSrv.timeRange();
+    let msRange = range.to.diff(range.from);
+    let regularRange = kbn.secondsToHms(msRange / 1000);
+    return {
+      __range_ms: { text: msRange, value: msRange },
+      __range: { text: regularRange, value: regularRange },
+    };
+  }
+
   annotationQuery(options) {
     var annotation = options.annotation;
     var expr = annotation.expr || '';

+ 42 - 1
public/app/plugins/datasource/prometheus/specs/datasource.jest.ts

@@ -2,6 +2,7 @@ import _ from 'lodash';
 import moment from 'moment';
 import q from 'q';
 import { alignRange, PrometheusDatasource, prometheusSpecialRegexEscape, prometheusRegularEscape } from '../datasource';
+jest.mock('../metric_find_query');
 
 describe('PrometheusDatasource', () => {
   let ctx: any = {};
@@ -18,7 +19,14 @@ describe('PrometheusDatasource', () => {
   ctx.templateSrvMock = {
     replace: a => a,
   };
-  ctx.timeSrvMock = {};
+  ctx.timeSrvMock = {
+    timeRange: () => {
+      return {
+        from: moment(1531468681),
+        to: moment(1531489712),
+      };
+    },
+  };
 
   beforeEach(() => {
     ctx.ds = new PrometheusDatasource(instanceSettings, q, ctx.backendSrvMock, ctx.templateSrvMock, ctx.timeSrvMock);
@@ -204,4 +212,37 @@ describe('PrometheusDatasource', () => {
       expect(prometheusSpecialRegexEscape('+looking$glass?')).toEqual('\\\\+looking\\\\$glass\\\\?');
     });
   });
+
+  describe('metricFindQuery', () => {
+    beforeEach(() => {
+      let query = 'query_result(topk(5,rate(http_request_duration_microseconds_count[$__interval])))';
+      ctx.templateSrvMock.replace = jest.fn();
+      ctx.timeSrvMock.timeRange = () => {
+        return {
+          from: moment(1531468681),
+          to: moment(1531489712),
+        };
+      };
+      ctx.ds = new PrometheusDatasource(instanceSettings, q, ctx.backendSrvMock, ctx.templateSrvMock, ctx.timeSrvMock);
+      ctx.ds.metricFindQuery(query);
+    });
+
+    it('should call templateSrv.replace with scopedVars', () => {
+      expect(ctx.templateSrvMock.replace.mock.calls[0][1]).toBeDefined();
+    });
+
+    it('should have the correct range and range_ms', () => {
+      let range = ctx.templateSrvMock.replace.mock.calls[0][1].__range;
+      let rangeMs = ctx.templateSrvMock.replace.mock.calls[0][1].__range_ms;
+      expect(range).toEqual({ text: '21s', value: '21s' });
+      expect(rangeMs).toEqual({ text: 21031, value: 21031 });
+    });
+
+    it('should pass the default interval value', () => {
+      let interval = ctx.templateSrvMock.replace.mock.calls[0][1].__interval;
+      let intervalMs = ctx.templateSrvMock.replace.mock.calls[0][1].__interval_ms;
+      expect(interval).toEqual({ text: '15s', value: '15s' });
+      expect(intervalMs).toEqual({ text: 15000, value: 15000 });
+    });
+  });
 });