From 26d71c90f5b62b566c3ed1f0abad581b5adbaec9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Hugo=20H=C3=A4ggmark?= Date: Wed, 5 Feb 2020 16:40:37 +0100 Subject: [PATCH] Prometheus: Fixes default step value for annotation query (#21934) Fixes #21914 --- .../datasource/prometheus/datasource.test.ts | 41 +++++++++++++++++-- .../datasource/prometheus/datasource.ts | 33 ++++++++++----- .../datasource/prometheus/module.test.ts | 6 +++ .../plugins/datasource/prometheus/module.ts | 3 +- .../partials/annotations.editor.html | 2 +- 5 files changed, 68 insertions(+), 17 deletions(-) diff --git a/public/app/plugins/datasource/prometheus/datasource.test.ts b/public/app/plugins/datasource/prometheus/datasource.test.ts index a842035588e..3cb4375e14d 100644 --- a/public/app/plugins/datasource/prometheus/datasource.test.ts +++ b/public/app/plugins/datasource/prometheus/datasource.test.ts @@ -7,11 +7,11 @@ import { prometheusSpecialRegexEscape, } from './datasource'; import { - DataSourceInstanceSettings, - DataQueryResponseData, - DataQueryRequest, - dateTime, CoreApp, + DataQueryRequest, + DataQueryResponseData, + DataSourceInstanceSettings, + dateTime, LoadingState, } from '@grafana/data'; import { PromOptions, PromQuery } from './types'; @@ -835,6 +835,23 @@ describe('PrometheusDatasource', () => { expect(req.url).toContain('step=60'); }); + it('should use default step for short range when annotation step is empty string', () => { + const query = { + ...options, + annotation: { + ...options.annotation, + step: '', + }, + range: { + from: time({ seconds: 63 }), + to: time({ seconds: 123 }), + }, + }; + ds.annotationQuery(query); + const req = datasourceRequestMock.mock.calls[0][0]; + expect(req.url).toContain('step=60'); + }); + it('should use custom step for short range', () => { const annotation = { ...options.annotation, @@ -890,6 +907,22 @@ describe('PrometheusDatasource', () => { }); }); + describe('createAnnotationQueryOptions', () => { + it.each` + options | expected + ${{}} | ${{ interval: '60s' }} + ${{ annotation: {} }} | ${{ annotation: {}, interval: '60s' }} + ${{ annotation: { step: undefined } }} | ${{ annotation: { step: undefined }, interval: '60s' }} + ${{ annotation: { step: null } }} | ${{ annotation: { step: null }, interval: '60s' }} + ${{ annotation: { step: '' } }} | ${{ annotation: { step: '' }, interval: '60s' }} + ${{ annotation: { step: 0 } }} | ${{ annotation: { step: 0 }, interval: '60s' }} + ${{ annotation: { step: 5 } }} | ${{ annotation: { step: 5 }, interval: '60s' }} + ${{ annotation: { step: '5m' } }} | ${{ annotation: { step: '5m' }, interval: '5m' }} + `("when called with options: '$options'", ({ options, expected }) => { + expect(ds.createAnnotationQueryOptions(options)).toEqual(expected); + }); + }); + describe('When resultFormat is table and instant = true', () => { let results: any; const query = { diff --git a/public/app/plugins/datasource/prometheus/datasource.ts b/public/app/plugins/datasource/prometheus/datasource.ts index e6c79faa424..3dce2877349 100644 --- a/public/app/plugins/datasource/prometheus/datasource.ts +++ b/public/app/plugins/datasource/prometheus/datasource.ts @@ -6,11 +6,6 @@ import $ from 'jquery'; import kbn from 'app/core/utils/kbn'; import { AnnotationEvent, - dateMath, - DateTime, - LoadingState, - TimeRange, - TimeSeries, CoreApp, DataQueryError, DataQueryRequest, @@ -18,9 +13,14 @@ import { DataQueryResponseData, DataSourceApi, DataSourceInstanceSettings, + dateMath, + DateTime, + LoadingState, ScopedVars, + TimeRange, + TimeSeries, } from '@grafana/data'; -import { from, merge, Observable, of, forkJoin } from 'rxjs'; +import { forkJoin, from, merge, Observable, of } from 'rxjs'; import { filter, map, tap } from 'rxjs/operators'; import PrometheusMetricFindQuery from './metric_find_query'; @@ -37,6 +37,8 @@ import templateSrv from 'app/features/templating/template_srv'; import { getTimeSrv } from 'app/features/dashboard/services/TimeSrv'; import TableModel from 'app/core/table_model'; +export const ANNOTATION_QUERY_STEP_DEFAULT = '60s'; + interface RequestOptions { method?: string; url?: string; @@ -520,9 +522,21 @@ export class PrometheusDatasource extends DataSourceApi }; } + createAnnotationQueryOptions = (options: any): DataQueryRequest => { + const annotation = options.annotation; + const interval = + annotation && annotation.step && typeof annotation.step === 'string' + ? annotation.step + : ANNOTATION_QUERY_STEP_DEFAULT; + return { + ...options, + interval, + }; + }; + async annotationQuery(options: any) { const annotation = options.annotation; - const { expr = '', tagKeys = '', titleFormat = '', textFormat = '', step = '60s' } = annotation; + const { expr = '', tagKeys = '', titleFormat = '', textFormat = '' } = annotation; if (!expr) { return Promise.resolve([]); @@ -530,10 +544,7 @@ export class PrometheusDatasource extends DataSourceApi const start = this.getPrometheusTime(options.range.from, false); const end = this.getPrometheusTime(options.range.to, true); - const queryOptions = { - ...options, - interval: step, - }; + const queryOptions = this.createAnnotationQueryOptions(options); // Unsetting min interval for accurate event resolution const minStep = '1s'; diff --git a/public/app/plugins/datasource/prometheus/module.test.ts b/public/app/plugins/datasource/prometheus/module.test.ts index 5ad08259639..f12182e4fc9 100644 --- a/public/app/plugins/datasource/prometheus/module.test.ts +++ b/public/app/plugins/datasource/prometheus/module.test.ts @@ -1,8 +1,14 @@ import { plugin as PrometheusDatasourcePlugin } from './module'; +import { ANNOTATION_QUERY_STEP_DEFAULT } from './datasource'; describe('module', () => { it('should have metrics query field in panels and Explore', () => { expect(PrometheusDatasourcePlugin.components.ExploreMetricsQueryField).toBeDefined(); expect(PrometheusDatasourcePlugin.components.QueryEditor).toBeDefined(); }); + it('should have stepDefaultValuePlaceholder set in annotations ctrl', () => { + expect(PrometheusDatasourcePlugin.components.AnnotationsQueryCtrl).toBeDefined(); + const annotationsCtrl = new PrometheusDatasourcePlugin.components.AnnotationsQueryCtrl(); + expect(annotationsCtrl.stepDefaultValuePlaceholder).toEqual(ANNOTATION_QUERY_STEP_DEFAULT); + }); }); diff --git a/public/app/plugins/datasource/prometheus/module.ts b/public/app/plugins/datasource/prometheus/module.ts index 5d767e5a4ba..df7e67d9f97 100644 --- a/public/app/plugins/datasource/prometheus/module.ts +++ b/public/app/plugins/datasource/prometheus/module.ts @@ -1,5 +1,5 @@ import { DataSourcePlugin } from '@grafana/data'; -import { PrometheusDatasource } from './datasource'; +import { ANNOTATION_QUERY_STEP_DEFAULT, PrometheusDatasource } from './datasource'; import { PromQueryEditor } from './components/PromQueryEditor'; import PromCheatSheet from './components/PromCheatSheet'; @@ -9,6 +9,7 @@ import { ConfigEditor } from './configuration/ConfigEditor'; class PrometheusAnnotationsQueryCtrl { static templateUrl = 'partials/annotations.editor.html'; + stepDefaultValuePlaceholder = ANNOTATION_QUERY_STEP_DEFAULT; } export const plugin = new DataSourcePlugin(PrometheusDatasource) diff --git a/public/app/plugins/datasource/prometheus/partials/annotations.editor.html b/public/app/plugins/datasource/prometheus/partials/annotations.editor.html index 6e5982123fd..b7b0507a879 100644 --- a/public/app/plugins/datasource/prometheus/partials/annotations.editor.html +++ b/public/app/plugins/datasource/prometheus/partials/annotations.editor.html @@ -5,7 +5,7 @@
step - +