Explore: Moves PromContext from query level to DataQueryRequest level (#21260)

Closes #19598

Fixes bug introduced recently where the new PromQueryEditor did not preserve
the PromContext.Explore set on the query model by PromQueryField which caused
the table to be empty for Prometheus in explore.
pull/21247/head
Torkel Ödegaard 5 years ago committed by GitHub
parent 545b72da33
commit 45b7de1910
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 5
      packages/grafana-data/src/types/app.ts
  2. 2
      packages/grafana-data/src/types/datasource.ts
  3. 2
      public/app/core/utils/explore.ts
  4. 2
      public/app/features/dashboard/state/PanelQueryRunner.ts
  5. 5
      public/app/features/explore/TableContainer.tsx
  6. 2
      public/app/plugins/datasource/loki/language_provider.ts
  7. 4
      public/app/plugins/datasource/prometheus/components/PromQueryField.tsx
  8. 35
      public/app/plugins/datasource/prometheus/datasource.test.ts
  9. 12
      public/app/plugins/datasource/prometheus/datasource.ts
  10. 6
      public/app/plugins/datasource/prometheus/types.ts
  11. 3
      public/test/helpers/getQueryOptions.ts

@ -3,6 +3,11 @@ import { KeyValue } from './data';
import { NavModel } from './navModel';
import { PluginMeta, GrafanaPlugin, PluginIncludeType } from './plugin';
export enum CoreApp {
Dashboard = 'dashboard',
Explore = 'explore',
}
export interface AppRootProps<T = KeyValue> {
meta: AppPluginMeta<T>;

@ -7,6 +7,7 @@ import { AnnotationEvent, KeyValue, LoadingState, TableData, TimeSeries } from '
import { DataFrame, DataFrameDTO } from './dataFrame';
import { RawTimeRange, TimeRange, AbsoluteTimeRange } from './time';
import { ScopedVars } from './ScopedVars';
import { CoreApp } from './app';
export interface DataSourcePluginOptionsEditorProps<JSONData = DataSourceJsonData, SecureJSONData = {}> {
options: DataSourceSettings<JSONData, SecureJSONData>;
@ -449,6 +450,7 @@ export interface DataQueryRequest<TQuery extends DataQuery = DataQuery> {
scopedVars: ScopedVars;
targets: TQuery[];
timezone: string;
app: CoreApp | string;
cacheTimeout?: string;
exploreMode?: 'Logs' | 'Metrics';

@ -4,6 +4,7 @@ import { Unsubscribable } from 'rxjs';
// Services & Utils
import {
DataQuery,
CoreApp,
DataQueryError,
DataQueryRequest,
DataSourceApi,
@ -130,6 +131,7 @@ export function buildQueryTransaction(
const panelId = `${key}`;
const request: DataQueryRequest = {
app: CoreApp.Explore,
dashboardId: 0,
// TODO probably should be taken from preferences but does not seem to be used anyway.
timezone: DefaultTimeZone,

@ -15,6 +15,7 @@ import { runSharedRequest, isSharedDashboardQuery } from '../../../plugins/datas
import {
PanelData,
DataQuery,
CoreApp,
DataQueryRequest,
DataSourceApi,
DataSourceJsonData,
@ -106,6 +107,7 @@ export class PanelQueryRunner {
}
const request: DataQueryRequest = {
app: CoreApp.Dashboard,
requestId: getNextRequestId(),
timezone,
panelId,

@ -6,6 +6,8 @@ import { Table, Collapse } from '@grafana/ui';
import { ExploreId, ExploreItemState } from 'app/types/explore';
import { StoreState } from 'app/types';
import { toggleTable } from './state/actions';
import { config } from 'app/core/config';
import { PANEL_BORDER } from 'app/core/constants';
interface TableContainerProps {
exploreId: ExploreId;
@ -37,8 +39,7 @@ export class TableContainer extends PureComponent<TableContainerProps> {
const { loading, onClickCell, showingTable, tableResult, width } = this.props;
const height = this.getTableHeight();
const paddingWidth = 16;
const tableWidth = width - paddingWidth;
const tableWidth = width - config.theme.panelPadding * 2 - PANEL_BORDER;
return (
<Collapse label="Table" loading={loading} collapsible isOpen={showingTable} onToggle={this.onClickTableButton}>

@ -262,7 +262,7 @@ export default class LokiLanguageProvider extends LanguageProvider {
return Promise.all(
queries.map(async query => {
const expr = await this.importPrometheusQuery(query.expr);
const { context, ...rest } = query as PromQuery;
const { ...rest } = query as PromQuery;
return {
...rest,
expr,

@ -15,7 +15,7 @@ import {
import Prism from 'prismjs';
// dom also includes Element polyfills
import { PromQuery, PromContext, PromOptions, PromMetricsMetadata } from '../types';
import { PromQuery, PromOptions, PromMetricsMetadata } from '../types';
import { CancelablePromise, makePromiseCancelable } from 'app/core/utils/CancelablePromise';
import { ExploreQueryFieldProps, QueryHint, isDataFrame, toLegacyResponseData, HistoryItem } from '@grafana/data';
import { DOMUtil, SuggestionsState } from '@grafana/ui';
@ -220,7 +220,7 @@ class PromQueryField extends React.PureComponent<PromQueryFieldProps, PromQueryF
// Send text change to parent
const { query, onChange, onRunQuery } = this.props;
if (onChange) {
const nextQuery: PromQuery = { ...query, expr: value, context: PromContext.Explore };
const nextQuery: PromQuery = { ...query, expr: value };
onChange(nextQuery);
if (override && onRunQuery) {

@ -11,9 +11,10 @@ import {
DataQueryResponseData,
DataQueryRequest,
dateTime,
CoreApp,
LoadingState,
} from '@grafana/data';
import { PromOptions, PromQuery, PromContext } from './types';
import { PromOptions, PromQuery } from './types';
import templateSrv from 'app/features/templating/template_srv';
import { getTimeSrv, TimeSrv } from 'app/features/dashboard/services/TimeSrv';
import { CustomVariable } from 'app/features/templating/custom_variable';
@ -70,7 +71,7 @@ describe('PrometheusDatasource', () => {
it('returns empty array when no queries', done => {
expect.assertions(2);
ds.query(makeQuery([])).subscribe({
ds.query(createDataRequest([])).subscribe({
next(next) {
expect(next.data).toEqual([]);
expect(next.state).toBe(LoadingState.Done);
@ -84,7 +85,7 @@ describe('PrometheusDatasource', () => {
it('performs time series queries', done => {
expect.assertions(2);
ds.query(makeQuery([{}])).subscribe({
ds.query(createDataRequest([{}])).subscribe({
next(next) {
expect(next.data.length).not.toBe(0);
expect(next.state).toBe(LoadingState.Done);
@ -99,7 +100,7 @@ describe('PrometheusDatasource', () => {
expect.assertions(4);
const responseStatus = [LoadingState.Loading, LoadingState.Done];
ds.query(makeQuery([{ context: PromContext.Explore }, { context: PromContext.Explore }])).subscribe({
ds.query(createDataRequest([{}, {}], { app: CoreApp.Explore })).subscribe({
next(next) {
expect(next.data.length).not.toBe(0);
expect(next.state).toBe(responseStatus.shift());
@ -112,7 +113,7 @@ describe('PrometheusDatasource', () => {
it('with 2 queries and used from Panel, waits for all to finish until sending Done status', done => {
expect.assertions(2);
ds.query(makeQuery([{ context: PromContext.Panel }, { context: PromContext.Panel }])).subscribe({
ds.query(createDataRequest([{}, {}], { app: CoreApp.Dashboard })).subscribe({
next(next) {
expect(next.data.length).not.toBe(0);
expect(next.state).toBe(LoadingState.Done);
@ -1552,7 +1553,7 @@ describe('PrometheusDatasource for POST', () => {
});
});
const getPrepareTargetsContext = (target: PromQuery) => {
const getPrepareTargetsContext = (target: PromQuery, app?: CoreApp) => {
const instanceSettings = ({
url: 'proxied',
directUrl: 'direct',
@ -1563,7 +1564,7 @@ const getPrepareTargetsContext = (target: PromQuery) => {
const start = 0;
const end = 1;
const panelId = '2';
const options = ({ targets: [target], interval: '1s', panelId } as any) as DataQueryRequest<PromQuery>;
const options = ({ targets: [target], interval: '1s', panelId, app } as any) as DataQueryRequest<PromQuery>;
const ds = new PrometheusDatasource(instanceSettings);
const { queries, activeTargets } = ds.prepareTargets(options, start, end);
@ -1583,7 +1584,6 @@ describe('prepareTargets', () => {
const target: PromQuery = {
refId: 'A',
expr: 'up',
context: PromContext.Panel,
};
const { queries, activeTargets, panelId, end, start } = getPrepareTargetsContext(target);
@ -1614,12 +1614,11 @@ describe('prepareTargets', () => {
const target: PromQuery = {
refId: 'A',
expr: 'up',
context: PromContext.Explore,
showingGraph: true,
showingTable: true,
};
const { queries, activeTargets, panelId, end, start } = getPrepareTargetsContext(target);
const { queries, activeTargets, panelId, end, start } = getPrepareTargetsContext(target, CoreApp.Explore);
expect(queries.length).toBe(2);
expect(activeTargets.length).toBe(2);
@ -1672,12 +1671,11 @@ describe('prepareTargets', () => {
const target: PromQuery = {
refId: 'A',
expr: 'up',
context: PromContext.Explore,
showingGraph: false,
showingTable: false,
};
const { queries, activeTargets } = getPrepareTargetsContext(target);
const { queries, activeTargets } = getPrepareTargetsContext(target, CoreApp.Explore);
expect(queries.length).toBe(0);
expect(activeTargets.length).toBe(0);
@ -1689,12 +1687,11 @@ describe('prepareTargets', () => {
const target: PromQuery = {
refId: 'A',
expr: 'up',
context: PromContext.Explore,
showingGraph: false,
showingTable: true,
};
const { queries, activeTargets, panelId, end, start } = getPrepareTargetsContext(target);
const { queries, activeTargets, panelId, end, start } = getPrepareTargetsContext(target, CoreApp.Explore);
expect(queries.length).toBe(1);
expect(activeTargets.length).toBe(1);
@ -1727,12 +1724,11 @@ describe('prepareTargets', () => {
const target: PromQuery = {
refId: 'A',
expr: 'up',
context: PromContext.Explore,
showingGraph: true,
showingTable: false,
};
const { queries, activeTargets, panelId, end, start } = getPrepareTargetsContext(target);
const { queries, activeTargets, panelId, end, start } = getPrepareTargetsContext(target, CoreApp.Explore);
expect(queries.length).toBe(1);
expect(activeTargets.length).toBe(1);
@ -1761,8 +1757,9 @@ describe('prepareTargets', () => {
});
});
function makeQuery(targets: any[]): any {
return {
function createDataRequest(targets: any[], overrides?: Partial<DataQueryRequest>): DataQueryRequest<PromQuery> {
const defaults = {
app: CoreApp.Dashboard,
targets: targets.map(t => {
return {
instant: false,
@ -1779,4 +1776,6 @@ function makeQuery(targets: any[]): any {
},
interval: '15s',
};
return Object.assign(defaults, overrides || {}) as DataQueryRequest<PromQuery>;
}

@ -11,6 +11,7 @@ import {
LoadingState,
TimeRange,
TimeSeries,
CoreApp,
DataQueryError,
DataQueryRequest,
DataQueryResponse,
@ -29,7 +30,7 @@ import addLabelToQuery from './add_label_to_query';
import { getQueryHints } from './query_hints';
import { expandRecordingRules } from './language_utils';
// Types
import { PromContext, PromOptions, PromQuery, PromQueryRequest } from './types';
import { PromOptions, PromQuery, PromQueryRequest } from './types';
import { safeStringifyValue } from 'app/core/utils/explore';
import templateSrv from 'app/features/templating/template_srv';
import { getTimeSrv } from 'app/features/dashboard/services/TimeSrv';
@ -202,7 +203,7 @@ export class PrometheusDatasource extends DataSourceApi<PromQuery, PromOptions>
target.requestId = options.panelId + target.refId;
if (target.context !== PromContext.Explore) {
if (options.app !== CoreApp.Explore) {
activeTargets.push(target);
queries.push(this.createQuery(target, options, start, end));
continue;
@ -237,11 +238,6 @@ export class PrometheusDatasource extends DataSourceApi<PromQuery, PromOptions>
};
};
calledFromExplore = (options: DataQueryRequest<PromQuery>): boolean => {
const exploreTargets = options.targets.filter(target => target.context === PromContext.Explore).length;
return exploreTargets === options.targets.length;
};
query(options: DataQueryRequest<PromQuery>): Observable<DataQueryResponse> {
const start = this.getPrometheusTime(options.range.from, false);
const end = this.getPrometheusTime(options.range.to, true);
@ -255,7 +251,7 @@ export class PrometheusDatasource extends DataSourceApi<PromQuery, PromOptions>
});
}
if (this.calledFromExplore(options)) {
if (options.app === CoreApp.Explore) {
return this.exploreQuery(queries, activeTargets, end);
}

@ -1,13 +1,7 @@
import { DataQuery, DataSourceJsonData } from '@grafana/data';
export enum PromContext {
Explore = 'explore',
Panel = 'panel',
}
export interface PromQuery extends DataQuery {
expr: string;
context?: PromContext;
format?: string;
instant?: boolean;
hinting?: boolean;

@ -1,4 +1,4 @@
import { DataQueryRequest, DataQuery } from '@grafana/data';
import { DataQueryRequest, DataQuery, CoreApp } from '@grafana/data';
import { dateTime } from '@grafana/data';
export function getQueryOptions<TQuery extends DataQuery>(
@ -9,6 +9,7 @@ export function getQueryOptions<TQuery extends DataQuery>(
const defaults: DataQueryRequest<TQuery> = {
requestId: 'TEST',
app: CoreApp.Dashboard,
range: range,
targets: [],
scopedVars: {},

Loading…
Cancel
Save