Loki: Run instant query only in Explore (#27974)

* Run instant query only in Explore

* Replace forEach with for loop
This commit is contained in:
Ivana Huckova
2020-10-04 21:41:12 +02:00
committed by GitHub
parent 301d298bff
commit 0ffd9a9a3c
2 changed files with 61 additions and 10 deletions

View File

@@ -1,7 +1,15 @@
import { of, Subject } from 'rxjs'; import { of, Subject } from 'rxjs';
import { first, last, take } from 'rxjs/operators'; import { first, last, take } from 'rxjs/operators';
import { omit } from 'lodash'; import { omit } from 'lodash';
import { AnnotationQueryRequest, DataFrame, DataQueryResponse, dateTime, FieldCache, TimeRange } from '@grafana/data'; import {
AnnotationQueryRequest,
CoreApp,
DataFrame,
DataQueryResponse,
dateTime,
FieldCache,
TimeRange,
} from '@grafana/data';
import { BackendSrvRequest, FetchResponse } from '@grafana/runtime'; import { BackendSrvRequest, FetchResponse } from '@grafana/runtime';
import LokiDatasource from './datasource'; import LokiDatasource from './datasource';
@@ -130,7 +138,7 @@ describe('LokiDatasource', () => {
observableTester().subscribeAndExpectOnComplete<DataQueryResponse>({ observableTester().subscribeAndExpectOnComplete<DataQueryResponse>({
observable: ds.query(options).pipe(take(1)), observable: ds.query(options).pipe(take(1)),
expect: () => { expect: () => {
expect(fetchMock.mock.calls.length).toBe(2); expect(fetchMock.mock.calls.length).toBe(1);
expect(fetchMock.mock.calls[0][0].url).toContain(`limit=${expectedLimit}`); expect(fetchMock.mock.calls[0][0].url).toContain(`limit=${expectedLimit}`);
}, },
done, done,
@@ -171,10 +179,11 @@ describe('LokiDatasource', () => {
}); });
describe('when querying', () => { describe('when querying', () => {
it('should run range and instant query', done => { it('should run range and instant query in Explore', done => {
const ds = createLokiDSForTests(); const ds = createLokiDSForTests();
const options = getQueryOptions<LokiQuery>({ const options = getQueryOptions<LokiQuery>({
targets: [{ expr: '{job="grafana"}', refId: 'B' }], targets: [{ expr: '{job="grafana"}', refId: 'B' }],
app: CoreApp.Explore,
}); });
ds.runInstantQuery = jest.fn(() => of({ data: [] })); ds.runInstantQuery = jest.fn(() => of({ data: [] }));
@@ -190,10 +199,29 @@ describe('LokiDatasource', () => {
}); });
}); });
it('should return series data', done => { it('should run only range query in Dashboard', done => {
const ds = createLokiDSForTests();
const options = getQueryOptions<LokiQuery>({
targets: [{ expr: '{job="grafana"}', refId: 'B' }],
});
ds.runInstantQuery = jest.fn(() => of({ data: [] }));
ds.runRangeQuery = jest.fn(() => of({ data: [] }));
observableTester().subscribeAndExpectOnComplete<DataQueryResponse>({
observable: ds.query(options),
expect: () => {
expect(ds.runRangeQuery).toBeCalled();
},
done,
});
});
it('should return series data for both queries in Explore', done => {
const ds = createLokiDSForTests(); const ds = createLokiDSForTests();
const options = getQueryOptions<LokiQuery>({ const options = getQueryOptions<LokiQuery>({
targets: [{ expr: '{job="grafana"} |= "foo"', refId: 'B' }], targets: [{ expr: '{job="grafana"} |= "foo"', refId: 'B' }],
app: CoreApp.Explore,
}); });
observableTester().subscribeAndExpectOnNext<DataQueryResponse>({ observableTester().subscribeAndExpectOnNext<DataQueryResponse>({
@@ -223,6 +251,28 @@ describe('LokiDatasource', () => {
fetchStream.next(omit(testResponse, 'data.status')); fetchStream.next(omit(testResponse, 'data.status'));
}); });
it('should return series data for range query in Dashboard', done => {
const ds = createLokiDSForTests();
const options = getQueryOptions<LokiQuery>({
targets: [{ expr: '{job="grafana"} |= "foo"', refId: 'B' }],
});
observableTester().subscribeAndExpectOnNext<DataQueryResponse>({
observable: ds.query(options).pipe(first()), // first result will come from runRangeQuery
expect: res => {
const dataFrame = res.data[0] as DataFrame;
const fieldCache = new FieldCache(dataFrame);
expect(fieldCache.getFieldByName('line')?.values.get(0)).toBe('hello');
expect(dataFrame.meta?.limit).toBe(20);
expect(dataFrame.meta?.searchWords).toEqual(['foo']);
},
done,
});
fetchStream.next(testResponse);
fetchStream.next(omit(testResponse, 'data.status'));
});
it('should return custom error message when Loki returns escaping error', done => { it('should return custom error message when Loki returns escaping error', done => {
const ds = createLokiDSForTests(); const ds = createLokiDSForTests();
const options = getQueryOptions<LokiQuery>({ const options = getQueryOptions<LokiQuery>({

View File

@@ -23,6 +23,7 @@ import {
QueryResultMeta, QueryResultMeta,
ScopedVars, ScopedVars,
TimeRange, TimeRange,
CoreApp,
} from '@grafana/data'; } from '@grafana/data';
import { getTemplateSrv, TemplateSrv, BackendSrvRequest, FetchError, getBackendSrv } from '@grafana/runtime'; import { getTemplateSrv, TemplateSrv, BackendSrvRequest, FetchError, getBackendSrv } from '@grafana/runtime';
import { addLabelToQuery } from 'app/plugins/datasource/prometheus/add_label_to_query'; import { addLabelToQuery } from 'app/plugins/datasource/prometheus/add_label_to_query';
@@ -95,12 +96,12 @@ export class LokiDatasource extends DataSourceApi<LokiQuery, LokiOptions> {
expr: this.templateSrv.replace(target.expr, options.scopedVars, this.interpolateQueryExpr), expr: this.templateSrv.replace(target.expr, options.scopedVars, this.interpolateQueryExpr),
})); }));
filteredTargets.forEach(target => for (const target of filteredTargets) {
subQueries.push( if (options.app === CoreApp.Explore) {
this.runInstantQuery(target, options, filteredTargets.length), subQueries.push(this.runInstantQuery(target, options, filteredTargets.length));
this.runRangeQuery(target, options, filteredTargets.length) }
) subQueries.push(this.runRangeQuery(target, options, filteredTargets.length));
); }
// No valid targets, return the empty result to save a round trip. // No valid targets, return the empty result to save a round trip.
if (isEmpty(subQueries)) { if (isEmpty(subQueries)) {