Browse Source

Add support for interval in query variable

Add range to scopedVars

Add basic tests and extract function for range vars

Add support for range query variable in createQuery

Template vars squash
Tobias Skarhed 7 years ago
parent
commit
6b6a23ff6a

+ 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 });
+    });
+  });
 });