Ver código fonte

17278 prometheus step align utc (#17477)

* Update datasource.ts

* Update datasource.test.ts

* utcOffset reverse

from moment docs, utcOffset "function returns the real offset from UTC, not the reverse offset"

* add utcOffset() to DateTime interface

method returns the UTC offset as a number of minutes

* Fixed test
fxmiii 6 anos atrás
pai
commit
19185bd0af

+ 1 - 0
packages/grafana-ui/src/utils/moment_wrapper.ts

@@ -68,6 +68,7 @@ export interface DateTime extends Object {
   valueOf: () => number;
   unix: () => number;
   utc: () => DateTime;
+  utcOffset: () => number;
   hour?: () => number;
 }
 

+ 10 - 4
public/app/plugins/datasource/prometheus/datasource.ts

@@ -367,7 +367,7 @@ export class PrometheusDatasource extends DataSourceApi<PromQuery, PromOptions>
 
     // Align query interval with step to allow query caching and to ensure
     // that about-same-time query results look the same.
-    const adjusted = alignRange(start, end, query.step);
+    const adjusted = alignRange(start, end, query.step, this.timeSrv.timeRange().to.utcOffset() * 60);
     query.start = adjusted.start;
     query.end = adjusted.end;
     this._addTracingHeaders(query, options);
@@ -694,10 +694,16 @@ export class PrometheusDatasource extends DataSourceApi<PromQuery, PromOptions>
  * @param start Timestamp marking the beginning of the range.
  * @param end Timestamp marking the end of the range.
  * @param step Interval to align start and end with.
+ * @param utcOffsetSec Number of seconds current timezone is offset from UTC
  */
-export function alignRange(start: number, end: number, step: number): { end: number; start: number } {
-  const alignedEnd = Math.floor(end / step) * step;
-  const alignedStart = Math.floor(start / step) * step;
+export function alignRange(
+  start: number,
+  end: number,
+  step: number,
+  utcOffsetSec: number
+): { end: number; start: number } {
+  const alignedEnd = Math.floor((end + utcOffsetSec) / step) * step - utcOffsetSec;
+  const alignedStart = Math.floor((start + utcOffsetSec) / step) * step - utcOffsetSec;
   return {
     end: alignedEnd,
     start: alignedStart,

+ 20 - 5
public/app/plugins/datasource/prometheus/specs/datasource.test.ts

@@ -219,25 +219,37 @@ describe('PrometheusDatasource', () => {
 
   describe('alignRange', () => {
     it('does not modify already aligned intervals with perfect step', () => {
-      const range = alignRange(0, 3, 3);
+      const range = alignRange(0, 3, 3, 0);
       expect(range.start).toEqual(0);
       expect(range.end).toEqual(3);
     });
     it('does modify end-aligned intervals to reflect number of steps possible', () => {
-      const range = alignRange(1, 6, 3);
+      const range = alignRange(1, 6, 3, 0);
       expect(range.start).toEqual(0);
       expect(range.end).toEqual(6);
     });
     it('does align intervals that are a multiple of steps', () => {
-      const range = alignRange(1, 4, 3);
+      const range = alignRange(1, 4, 3, 0);
       expect(range.start).toEqual(0);
       expect(range.end).toEqual(3);
     });
     it('does align intervals that are not a multiple of steps', () => {
-      const range = alignRange(1, 5, 3);
+      const range = alignRange(1, 5, 3, 0);
       expect(range.start).toEqual(0);
       expect(range.end).toEqual(3);
     });
+    it('does align intervals with local midnight -UTC offset', () => {
+      //week range, location 4+ hours UTC offset, 24h step time
+      const range = alignRange(4 * 60 * 60, (7 * 24 + 4) * 60 * 60, 24 * 60 * 60, -4 * 60 * 60); //04:00 UTC, 7 day range
+      expect(range.start).toEqual(4 * 60 * 60);
+      expect(range.end).toEqual((7 * 24 + 4) * 60 * 60);
+    });
+    it('does align intervals with local midnight +UTC offset', () => {
+      //week range, location 4- hours UTC offset, 24h step time
+      const range = alignRange(20 * 60 * 60, (8 * 24 - 4) * 60 * 60, 24 * 60 * 60, 4 * 60 * 60); //20:00 UTC on day1, 7 days later is 20:00 on day8
+      expect(range.start).toEqual(20 * 60 * 60);
+      expect(range.end).toEqual((8 * 24 - 4) * 60 * 60);
+    });
   });
 
   describe('extractRuleMappingFromGroups()', () => {
@@ -419,7 +431,10 @@ const templateSrv = ({
 
 const timeSrv = ({
   timeRange: () => {
-    return { to: { diff: () => 2000 }, from: '' };
+    return {
+      from: dateTime(1531468681),
+      to: dateTime(1531468681 + 2000),
+    };
   },
 } as unknown) as TimeSrv;