mirror of
https://github.com/grafana/grafana.git
synced 2025-02-16 18:34:52 -06:00
Prometheus: Fixes so results in Panel always are sorted by query order (#19597)
Fixes #19529
This commit is contained in:
parent
2fb301ccaf
commit
f9611250ea
@ -1,6 +1,6 @@
|
|||||||
import { PrometheusDatasource } from './datasource';
|
import { PrometheusDatasource } from './datasource';
|
||||||
import { DataSourceInstanceSettings } from '@grafana/ui';
|
import { DataSourceInstanceSettings } from '@grafana/ui';
|
||||||
import { PromOptions } from './types';
|
import { PromContext, PromOptions } from './types';
|
||||||
import { dateTime, LoadingState } from '@grafana/data';
|
import { dateTime, LoadingState } from '@grafana/data';
|
||||||
|
|
||||||
const defaultInstanceSettings: DataSourceInstanceSettings<PromOptions> = {
|
const defaultInstanceSettings: DataSourceInstanceSettings<PromOptions> = {
|
||||||
@ -67,11 +67,11 @@ describe('datasource', () => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('with 2 queries, waits for all to finish until sending Done status', done => {
|
it('with 2 queries and used from Explore, sends results as they arrive', done => {
|
||||||
expect.assertions(4);
|
expect.assertions(4);
|
||||||
backendSrvMock.datasourceRequest.mockReturnValue(Promise.resolve(makePromResponse()));
|
backendSrvMock.datasourceRequest.mockReturnValue(Promise.resolve(makePromResponse()));
|
||||||
const responseStatus = [LoadingState.Loading, LoadingState.Done];
|
const responseStatus = [LoadingState.Loading, LoadingState.Done];
|
||||||
ds.query(makeQuery([{}, {}])).subscribe({
|
ds.query(makeQuery([{ context: PromContext.Explore }, { context: PromContext.Explore }])).subscribe({
|
||||||
next(next) {
|
next(next) {
|
||||||
expect(next.data.length).not.toBe(0);
|
expect(next.data.length).not.toBe(0);
|
||||||
expect(next.state).toBe(responseStatus.shift());
|
expect(next.state).toBe(responseStatus.shift());
|
||||||
@ -81,6 +81,20 @@ describe('datasource', () => {
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('with 2 queries and used from Panel, waits for all to finish until sending Done status', done => {
|
||||||
|
expect.assertions(2);
|
||||||
|
backendSrvMock.datasourceRequest.mockReturnValue(Promise.resolve(makePromResponse()));
|
||||||
|
ds.query(makeQuery([{ context: PromContext.Panel }, { context: PromContext.Panel }])).subscribe({
|
||||||
|
next(next) {
|
||||||
|
expect(next.data.length).not.toBe(0);
|
||||||
|
expect(next.state).toBe(LoadingState.Done);
|
||||||
|
},
|
||||||
|
complete() {
|
||||||
|
done();
|
||||||
|
},
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -92,6 +106,7 @@ function makeQuery(targets: any[]): any {
|
|||||||
start: dateTime().subtract(5, 'minutes'),
|
start: dateTime().subtract(5, 'minutes'),
|
||||||
end: dateTime(),
|
end: dateTime(),
|
||||||
expr: 'test',
|
expr: 'test',
|
||||||
|
showingGraph: true,
|
||||||
...t,
|
...t,
|
||||||
};
|
};
|
||||||
}),
|
}),
|
||||||
|
@ -3,8 +3,8 @@ import _ from 'lodash';
|
|||||||
import $ from 'jquery';
|
import $ from 'jquery';
|
||||||
// Services & Utils
|
// Services & Utils
|
||||||
import kbn from 'app/core/utils/kbn';
|
import kbn from 'app/core/utils/kbn';
|
||||||
import { AnnotationEvent, dateMath, DateTime, LoadingState, TimeRange } from '@grafana/data';
|
import { AnnotationEvent, dateMath, DateTime, LoadingState, TimeRange, TimeSeries } from '@grafana/data';
|
||||||
import { from, merge, Observable, of } from 'rxjs';
|
import { from, merge, Observable, of, forkJoin } from 'rxjs';
|
||||||
import { filter, map, tap } from 'rxjs/operators';
|
import { filter, map, tap } from 'rxjs/operators';
|
||||||
|
|
||||||
import PrometheusMetricFindQuery from './metric_find_query';
|
import PrometheusMetricFindQuery from './metric_find_query';
|
||||||
@ -28,6 +28,7 @@ import { safeStringifyValue } from 'app/core/utils/explore';
|
|||||||
import { TemplateSrv } from 'app/features/templating/template_srv';
|
import { TemplateSrv } from 'app/features/templating/template_srv';
|
||||||
import { TimeSrv } from 'app/features/dashboard/services/TimeSrv';
|
import { TimeSrv } from 'app/features/dashboard/services/TimeSrv';
|
||||||
import { ExploreUrlState } from 'app/types';
|
import { ExploreUrlState } from 'app/types';
|
||||||
|
import TableModel from 'app/core/table_model';
|
||||||
|
|
||||||
export interface PromDataQueryResponse {
|
export interface PromDataQueryResponse {
|
||||||
data: {
|
data: {
|
||||||
@ -221,6 +222,18 @@ export class PrometheusDatasource extends DataSourceApi<PromQuery, PromOptions>
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
calledFromExplore = (options: DataQueryRequest<PromQuery>): boolean => {
|
||||||
|
let exploreTargets = 0;
|
||||||
|
for (let index = 0; index < options.targets.length; index++) {
|
||||||
|
const target = options.targets[index];
|
||||||
|
if (target.context === PromContext.Explore) {
|
||||||
|
exploreTargets++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return exploreTargets === options.targets.length;
|
||||||
|
};
|
||||||
|
|
||||||
query(options: DataQueryRequest<PromQuery>): Observable<DataQueryResponse> {
|
query(options: DataQueryRequest<PromQuery>): Observable<DataQueryResponse> {
|
||||||
const start = this.getPrometheusTime(options.range.from, false);
|
const start = this.getPrometheusTime(options.range.from, false);
|
||||||
const end = this.getPrometheusTime(options.range.to, true);
|
const end = this.getPrometheusTime(options.range.to, true);
|
||||||
@ -234,6 +247,14 @@ export class PrometheusDatasource extends DataSourceApi<PromQuery, PromOptions>
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (this.calledFromExplore(options)) {
|
||||||
|
return this.exploreQuery(queries, activeTargets, end);
|
||||||
|
}
|
||||||
|
|
||||||
|
return this.panelsQuery(queries, activeTargets, end, options.requestId);
|
||||||
|
}
|
||||||
|
|
||||||
|
private exploreQuery(queries: PromQueryRequest[], activeTargets: PromQuery[], end: number) {
|
||||||
let runningQueriesCount = queries.length;
|
let runningQueriesCount = queries.length;
|
||||||
const subQueries = queries.map((query, index) => {
|
const subQueries = queries.map((query, index) => {
|
||||||
const target = activeTargets[index];
|
const target = activeTargets[index];
|
||||||
@ -264,6 +285,40 @@ export class PrometheusDatasource extends DataSourceApi<PromQuery, PromOptions>
|
|||||||
return merge(...subQueries);
|
return merge(...subQueries);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private panelsQuery(queries: PromQueryRequest[], activeTargets: PromQuery[], end: number, requestId: string) {
|
||||||
|
const observables: Array<Observable<Array<TableModel | TimeSeries>>> = queries.map((query, index) => {
|
||||||
|
const target = activeTargets[index];
|
||||||
|
let observable: Observable<any> = null;
|
||||||
|
|
||||||
|
if (query.instant) {
|
||||||
|
observable = from(this.performInstantQuery(query, end));
|
||||||
|
} else {
|
||||||
|
observable = from(this.performTimeSeriesQuery(query, query.start, query.end));
|
||||||
|
}
|
||||||
|
|
||||||
|
return observable.pipe(
|
||||||
|
filter((response: any) => (response.cancelled ? false : true)),
|
||||||
|
map((response: any) => {
|
||||||
|
const data = this.processResult(response, query, target, queries.length);
|
||||||
|
return data;
|
||||||
|
})
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
return forkJoin(observables).pipe(
|
||||||
|
map((results: Array<Array<TableModel | TimeSeries>>) => {
|
||||||
|
const data = results.reduce((result, current) => {
|
||||||
|
return [...result, ...current];
|
||||||
|
}, []);
|
||||||
|
return {
|
||||||
|
data,
|
||||||
|
key: requestId,
|
||||||
|
state: LoadingState.Done,
|
||||||
|
};
|
||||||
|
})
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
createQuery(target: PromQuery, options: DataQueryRequest<PromQuery>, start: number, end: number) {
|
createQuery(target: PromQuery, options: DataQueryRequest<PromQuery>, start: number, end: number) {
|
||||||
const query: PromQueryRequest = {
|
const query: PromQueryRequest = {
|
||||||
hinting: target.hinting,
|
hinting: target.hinting,
|
||||||
|
Loading…
Reference in New Issue
Block a user