From 0c70308870e1748063b66274941772deba8cb76d Mon Sep 17 00:00:00 2001 From: Kemal Akkoyun Date: Tue, 29 Sep 2020 12:05:57 +0300 Subject: [PATCH] Prometheus: Add time range parameters to labels API (#27548) * Add time range parameters to labels API Signed-off-by: Kemal Akkoyun * Fix minor issues Signed-off-by: Kemal Akkoyun * Add range to explore component Signed-off-by: Kemal Akkoyun * Add range to query component Signed-off-by: Kemal Akkoyun * Cache metric names for time range Signed-off-by: Kemal Akkoyun * Update public/app/plugins/datasource/prometheus/components/PromQueryField.tsx Co-authored-by: Ivana Huckova <30407135+ivanahuckova@users.noreply.github.com> * Remove unused method Signed-off-by: Kemal Akkoyun * Only compare the ranges Signed-off-by: Kemal Akkoyun * Update public/app/plugins/datasource/prometheus/components/PromQueryField.tsx Co-authored-by: Ivana Huckova <30407135+ivanahuckova@users.noreply.github.com> Co-authored-by: Ivana Huckova <30407135+ivanahuckova@users.noreply.github.com> --- .../PromExploreQueryEditor.test.tsx | 11 ++++++- .../components/PromExploreQueryEditor.tsx | 3 +- .../prometheus/components/PromQueryEditor.tsx | 3 +- .../prometheus/components/PromQueryField.tsx | 26 +++++++++++++++-- .../PromExploreQueryEditor.test.tsx.snap | 10 +++++++ .../datasource/prometheus/datasource.test.ts | 20 ------------- .../datasource/prometheus/datasource.ts | 17 ++--------- .../prometheus/language_provider.ts | 17 +++++++++-- .../prometheus/metric_find_query.test.ts | 6 ++-- .../prometheus/metric_find_query.ts | 29 +++++++++++++++---- 10 files changed, 92 insertions(+), 50 deletions(-) diff --git a/public/app/plugins/datasource/prometheus/components/PromExploreQueryEditor.test.tsx b/public/app/plugins/datasource/prometheus/components/PromExploreQueryEditor.test.tsx index cfa935f7ff3..50777e801af 100644 --- a/public/app/plugins/datasource/prometheus/components/PromExploreQueryEditor.test.tsx +++ b/public/app/plugins/datasource/prometheus/components/PromExploreQueryEditor.test.tsx @@ -4,7 +4,7 @@ import { act } from 'react-dom/test-utils'; import PromExploreQueryEditor from './PromExploreQueryEditor'; import { PrometheusDatasource } from '../datasource'; import { PromQuery } from '../types'; -import { LoadingState, PanelData, toUtc } from '@grafana/data'; +import { LoadingState, PanelData, toUtc, TimeRange } from '@grafana/data'; const setup = (renderMethod: any, propOverrides?: object) => { const datasourceMock: unknown = {}; @@ -12,6 +12,14 @@ const setup = (renderMethod: any, propOverrides?: object) => { const onRunQuery = jest.fn(); const onChange = jest.fn(); const query: PromQuery = { expr: '', refId: 'A', interval: '1s' }; + const range: TimeRange = { + from: toUtc('2020-01-01', 'YYYY-MM-DD'), + to: toUtc('2020-01-02', 'YYYY-MM-DD'), + raw: { + from: toUtc('2020-01-01', 'YYYY-MM-DD'), + to: toUtc('2020-01-02', 'YYYY-MM-DD'), + }, + }; const data: PanelData = { state: LoadingState.NotStarted, series: [], @@ -50,6 +58,7 @@ const setup = (renderMethod: any, propOverrides?: object) => { const props: any = { query, data, + range, datasource, exploreMode, history, diff --git a/public/app/plugins/datasource/prometheus/components/PromExploreQueryEditor.tsx b/public/app/plugins/datasource/prometheus/components/PromExploreQueryEditor.tsx index 18dc1cdace0..171fa9f0c58 100644 --- a/public/app/plugins/datasource/prometheus/components/PromExploreQueryEditor.tsx +++ b/public/app/plugins/datasource/prometheus/components/PromExploreQueryEditor.tsx @@ -12,7 +12,7 @@ import { PromExploreExtraField } from './PromExploreExtraField'; export type Props = ExploreQueryFieldProps; export const PromExploreQueryEditor: FC = (props: Props) => { - const { query, data, datasource, history, onChange, onRunQuery } = props; + const { range, query, data, datasource, history, onChange, onRunQuery } = props; function onChangeQueryStep(value: string) { const { query, onChange } = props; @@ -49,6 +49,7 @@ export const PromExploreQueryEditor: FC = (props: Props) => { {}} diff --git a/public/app/plugins/datasource/prometheus/components/PromQueryEditor.tsx b/public/app/plugins/datasource/prometheus/components/PromQueryEditor.tsx index 659cf2a3cd3..f192cec75f6 100644 --- a/public/app/plugins/datasource/prometheus/components/PromQueryEditor.tsx +++ b/public/app/plugins/datasource/prometheus/components/PromQueryEditor.tsx @@ -96,7 +96,7 @@ export class PromQueryEditor extends PureComponent { }; render() { - const { datasource, query, data } = this.props; + const { datasource, query, range, data } = this.props; const { formatOption, instant, interval, intervalFactorOption, legendFormat } = this.state; return ( @@ -104,6 +104,7 @@ export class PromQueryEditor extends PureComponent { `; diff --git a/public/app/plugins/datasource/prometheus/datasource.test.ts b/public/app/plugins/datasource/prometheus/datasource.test.ts index f03f244a2b1..314f17ed69b 100644 --- a/public/app/plugins/datasource/prometheus/datasource.test.ts +++ b/public/app/plugins/datasource/prometheus/datasource.test.ts @@ -203,26 +203,6 @@ describe('PrometheusDatasource', () => { }); }); - describe('When performing performSuggestQuery', () => { - it('should cache response', async () => { - fetchMock.mockImplementation(() => - of({ - status: 'success', - data: { data: ['value1', 'value2', 'value3'] }, - }) - ); - - let results = await ds.performSuggestQuery('value', true); - - expect(results).toHaveLength(3); - - fetchMock.mockImplementation(jest.fn()); - results = await ds.performSuggestQuery('value', true); - - expect(results).toHaveLength(3); - }); - }); - describe('When converting prometheus histogram to heatmap format', () => { let query: any; beforeEach(() => { diff --git a/public/app/plugins/datasource/prometheus/datasource.ts b/public/app/plugins/datasource/prometheus/datasource.ts index 2d256642035..c92682db84d 100644 --- a/public/app/plugins/datasource/prometheus/datasource.ts +++ b/public/app/plugins/datasource/prometheus/datasource.ts @@ -1,5 +1,6 @@ // Libraries import cloneDeep from 'lodash/cloneDeep'; +import LRU from 'lru-cache'; // Services & Utils import { AnnotationEvent, @@ -66,7 +67,7 @@ export class PrometheusDatasource extends DataSourceApi directUrl: string; basicAuth: any; withCredentials: any; - metricsNameCache: any; + metricsNameCache = new LRU(10); interval: string; queryTimeout: string; httpMethod: string; @@ -527,20 +528,6 @@ export class PrometheusDatasource extends DataSourceApi return error; }; - async performSuggestQuery(query: string, cache = false) { - if (cache && this.metricsNameCache?.expire > Date.now()) { - return this.metricsNameCache.data.filter((metricName: any) => metricName.indexOf(query) !== 1); - } - - const response: PromLabelQueryResponse = await this.metadataRequest('/api/v1/label/__name__/values'); - this.metricsNameCache = { - data: response.data.data, - expire: Date.now() + 60 * 1000, - }; - - return response.data.data.filter(metricName => metricName.indexOf(query) !== 1); - } - metricFindQuery(query: string) { if (!query) { return Promise.resolve([]); diff --git a/public/app/plugins/datasource/prometheus/language_provider.ts b/public/app/plugins/datasource/prometheus/language_provider.ts index db99f63e136..629c842cd0a 100644 --- a/public/app/plugins/datasource/prometheus/language_provider.ts +++ b/public/app/plugins/datasource/prometheus/language_provider.ts @@ -114,7 +114,14 @@ export default class PromQlLanguageProvider extends LanguageProvider { return []; } - this.metrics = await this.request('/api/v1/label/__name__/values', []); + const tRange = this.datasource.getTimeRange(); + const params = new URLSearchParams({ + start: tRange['start'].toString(), + end: tRange['end'].toString(), + }); + const url = `/api/v1/label/__name__/values?${params.toString()}`; + + this.metrics = await this.request(url, []); this.lookupsDisabled = this.metrics.length > this.lookupMetricsThreshold; this.metricsMetadata = fixSummariesMetadata(await this.request('/api/v1/metadata', {})); this.processHistogramMetrics(this.metrics); @@ -404,7 +411,13 @@ export default class PromQlLanguageProvider extends LanguageProvider { } fetchLabelValues = async (key: string): Promise> => { - const data = await this.request(`/api/v1/label/${key}/values`, []); + const tRange = this.datasource.getTimeRange(); + const params = new URLSearchParams({ + start: tRange['start'].toString(), + end: tRange['end'].toString(), + }); + const url = `/api/v1/label/${key}/values?${params.toString()}`; + const data = await this.request(url, []); return { [key]: data }; }; diff --git a/public/app/plugins/datasource/prometheus/metric_find_query.test.ts b/public/app/plugins/datasource/prometheus/metric_find_query.test.ts index 55cb294ca30..8fc55ecba2f 100644 --- a/public/app/plugins/datasource/prometheus/metric_find_query.test.ts +++ b/public/app/plugins/datasource/prometheus/metric_find_query.test.ts @@ -76,7 +76,7 @@ describe('PrometheusMetricFindQuery', () => { expect(fetchMock).toHaveBeenCalledTimes(1); expect(fetchMock).toHaveBeenCalledWith({ method: 'GET', - url: 'proxied/api/v1/labels', + url: `proxied/api/v1/labels?start=${raw.from.unix()}&end=${raw.to.unix()}`, hideFromInspector: true, headers: {}, }); @@ -95,7 +95,7 @@ describe('PrometheusMetricFindQuery', () => { expect(fetchMock).toHaveBeenCalledTimes(1); expect(fetchMock).toHaveBeenCalledWith({ method: 'GET', - url: 'proxied/api/v1/label/resource/values', + url: `proxied/api/v1/label/resource/values?start=${raw.from.unix()}&end=${raw.to.unix()}`, hideFromInspector: true, headers: {}, }); @@ -190,7 +190,7 @@ describe('PrometheusMetricFindQuery', () => { expect(fetchMock).toHaveBeenCalledTimes(1); expect(fetchMock).toHaveBeenCalledWith({ method: 'GET', - url: 'proxied/api/v1/label/__name__/values', + url: `proxied/api/v1/label/__name__/values?start=${raw.from.unix()}&end=${raw.to.unix()}`, hideFromInspector: true, headers: {}, }); diff --git a/public/app/plugins/datasource/prometheus/metric_find_query.ts b/public/app/plugins/datasource/prometheus/metric_find_query.ts index 2b3d88ca003..ae4e9204463 100644 --- a/public/app/plugins/datasource/prometheus/metric_find_query.ts +++ b/public/app/plugins/datasource/prometheus/metric_find_query.ts @@ -48,7 +48,15 @@ export default class PrometheusMetricFindQuery { } labelNamesQuery() { - const url = '/api/v1/labels'; + const start = this.datasource.getPrometheusTime(this.range.from, false); + const end = this.datasource.getPrometheusTime(this.range.to, true); + const params = new URLSearchParams({ + start: start.toString(), + end: end.toString(), + }); + + const url = `/api/v1/labels?${params.toString()}`; + return this.datasource.metadataRequest(url).then((result: any) => { return _.map(result.data.data, value => { return { text: value }; @@ -57,11 +65,18 @@ export default class PrometheusMetricFindQuery { } labelValuesQuery(label: string, metric?: string) { + const start = this.datasource.getPrometheusTime(this.range.from, false); + const end = this.datasource.getPrometheusTime(this.range.to, true); + let url: string; if (!metric) { + const params = new URLSearchParams({ + start: start.toString(), + end: end.toString(), + }); // return label values globally - url = '/api/v1/label/' + label + '/values'; + url = `/api/v1/label/${label}/values?${params.toString()}`; return this.datasource.metadataRequest(url).then((result: any) => { return _.map(result.data.data, value => { @@ -69,8 +84,6 @@ export default class PrometheusMetricFindQuery { }); }); } else { - const start = this.datasource.getPrometheusTime(this.range.from, false); - const end = this.datasource.getPrometheusTime(this.range.to, true); const params = new URLSearchParams({ 'match[]': metric, start: start.toString(), @@ -96,7 +109,13 @@ export default class PrometheusMetricFindQuery { } metricNameQuery(metricFilterPattern: string) { - const url = '/api/v1/label/__name__/values'; + const start = this.datasource.getPrometheusTime(this.range.from, false); + const end = this.datasource.getPrometheusTime(this.range.to, true); + const params = new URLSearchParams({ + start: start.toString(), + end: end.toString(), + }); + const url = `/api/v1/label/__name__/values?${params.toString()}`; return this.datasource.metadataRequest(url).then((result: any) => { return _.chain(result.data.data)