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

Fix bar width issue in aligned prometheus queries (#12483)

* Fix bar width issue in aligned prometheus queries

This was broken because null values were filled in with unaligned times.

* use aligned times for result transformation
* add tests

An earlier version of this fix aligned the times again in the transformer, but
I think it's safe to only deal with aligned times in the response.

* Fixed prometheus heatmap tranformer test

The interval needs to be 1 to prevent step alignment.
David 7 лет назад
Родитель
Сommit
0d1f7c8782

+ 14 - 0
public/app/core/specs/time_series.jest.ts

@@ -119,6 +119,20 @@ describe('TimeSeries', function() {
       series.getFlotPairs('null');
       series.getFlotPairs('null');
       expect(series.stats.avg).toBe(null);
       expect(series.stats.avg).toBe(null);
     });
     });
+
+    it('calculates timeStep', function() {
+      series = new TimeSeries({
+        datapoints: [[null, 1], [null, 2], [null, 3]],
+      });
+      series.getFlotPairs('null');
+      expect(series.stats.timeStep).toBe(1);
+
+      series = new TimeSeries({
+        datapoints: [[0, 1530529290], [0, 1530529305], [0, 1530529320]],
+      });
+      series.getFlotPairs('null');
+      expect(series.stats.timeStep).toBe(15);
+    });
   });
   });
 
 
   describe('When checking if ms resolution is needed', function() {
   describe('When checking if ms resolution is needed', function() {

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

@@ -162,8 +162,8 @@ export class PrometheusDatasource {
           format: activeTargets[index].format,
           format: activeTargets[index].format,
           step: queries[index].step,
           step: queries[index].step,
           legendFormat: activeTargets[index].legendFormat,
           legendFormat: activeTargets[index].legendFormat,
-          start: start,
-          end: end,
+          start: queries[index].start,
+          end: queries[index].end,
           query: queries[index].expr,
           query: queries[index].expr,
           responseListLength: responseList.length,
           responseListLength: responseList.length,
           responseIndex: index,
           responseIndex: index,

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

@@ -68,7 +68,7 @@ describe('PrometheusDatasource', () => {
       ctx.query = {
       ctx.query = {
         range: { from: moment(1443454528000), to: moment(1443454528000) },
         range: { from: moment(1443454528000), to: moment(1443454528000) },
         targets: [{ expr: 'test{job="testjob"}', format: 'heatmap', legendFormat: '{{le}}' }],
         targets: [{ expr: 'test{job="testjob"}', format: 'heatmap', legendFormat: '{{le}}' }],
-        interval: '60s',
+        interval: '1s',
       };
       };
     });
     });
 
 

+ 78 - 0
public/app/plugins/datasource/prometheus/specs/result_transformer.jest.ts

@@ -127,4 +127,82 @@ describe('Prometheus Result Transformer', () => {
       ]);
       ]);
     });
     });
   });
   });
+
+  describe('When resultFormat is time series', () => {
+    it('should transform matrix into timeseries', () => {
+      const response = {
+        status: 'success',
+        data: {
+          resultType: 'matrix',
+          result: [
+            {
+              metric: { __name__: 'test', job: 'testjob' },
+              values: [[0, '10'], [1, '10'], [2, '0']],
+            },
+          ],
+        },
+      };
+      let result = [];
+      let options = {
+        format: 'timeseries',
+        start: 0,
+        end: 2,
+      };
+
+      ctx.resultTransformer.transform(result, { data: response }, options);
+      expect(result).toEqual([{ target: 'test{job="testjob"}', datapoints: [[10, 0], [10, 1000], [0, 2000]] }]);
+    });
+
+    it('should fill timeseries with null values', () => {
+      const response = {
+        status: 'success',
+        data: {
+          resultType: 'matrix',
+          result: [
+            {
+              metric: { __name__: 'test', job: 'testjob' },
+              values: [[1, '10'], [2, '0']],
+            },
+          ],
+        },
+      };
+      let result = [];
+      let options = {
+        format: 'timeseries',
+        step: 1,
+        start: 0,
+        end: 2,
+      };
+
+      ctx.resultTransformer.transform(result, { data: response }, options);
+      expect(result).toEqual([{ target: 'test{job="testjob"}', datapoints: [[null, 0], [10, 1000], [0, 2000]] }]);
+    });
+
+    it('should align null values with step', () => {
+      const response = {
+        status: 'success',
+        data: {
+          resultType: 'matrix',
+          result: [
+            {
+              metric: { __name__: 'test', job: 'testjob' },
+              values: [[4, '10'], [8, '10']],
+            },
+          ],
+        },
+      };
+      let result = [];
+      let options = {
+        format: 'timeseries',
+        step: 2,
+        start: 0,
+        end: 8,
+      };
+
+      ctx.resultTransformer.transform(result, { data: response }, options);
+      expect(result).toEqual([
+        { target: 'test{job="testjob"}', datapoints: [[null, 0], [null, 2000], [10, 4000], [null, 6000], [10, 8000]] },
+      ]);
+    });
+  });
 });
 });