From 546818819bf833c0d68b5bee6d84d7dc1bef0bde Mon Sep 17 00:00:00 2001 From: Ryan McKinley Date: Fri, 7 Jan 2022 10:00:11 -0800 Subject: [PATCH] Loki: use queryType rather than range|instant flags (#43727) --- pkg/tsdb/loki/loki.go | 1 + .../components/AnnotationsQueryEditor.tsx | 1 - .../components/LokiExploreQueryEditor.tsx | 1 - .../loki/components/LokiOptionFields.tsx | 30 +++++++++---------- .../loki/components/LokiQueryEditor.tsx | 1 - .../LokiExploreQueryEditor.test.tsx.snap | 1 - .../LokiQueryEditor.test.tsx.snap | 2 -- .../app/plugins/datasource/loki/datasource.ts | 4 ++- .../datasource/loki/language_provider.test.ts | 3 +- .../datasource/loki/language_provider.ts | 10 +++++-- public/app/plugins/datasource/loki/types.ts | 13 +++++++- .../datasource/prometheus/language_utils.ts | 8 +++-- 12 files changed, 46 insertions(+), 29 deletions(-) diff --git a/pkg/tsdb/loki/loki.go b/pkg/tsdb/loki/loki.go index 1a74118b0e9..5c5c6a804bc 100644 --- a/pkg/tsdb/loki/loki.go +++ b/pkg/tsdb/loki/loki.go @@ -69,6 +69,7 @@ type datasourceInfo struct { } type QueryModel struct { + QueryType string `json:"queryType"` Expr string `json:"expr"` LegendFormat string `json:"legendFormat"` Interval string `json:"interval"` diff --git a/public/app/plugins/datasource/loki/components/AnnotationsQueryEditor.tsx b/public/app/plugins/datasource/loki/components/AnnotationsQueryEditor.tsx index 467d566efa3..98af4ae0eb5 100644 --- a/public/app/plugins/datasource/loki/components/AnnotationsQueryEditor.tsx +++ b/public/app/plugins/datasource/loki/components/AnnotationsQueryEditor.tsx @@ -34,7 +34,6 @@ export const LokiAnnotationsQueryEditor = memo(function LokiAnnotationQueryEdito history={[]} ExtraFieldElement={ void; onRunQuery: () => void; runOnBlur?: boolean; } -type LokiQueryType = 'instant' | 'range'; - const queryTypeOptions: Array> = [ - { value: 'range', label: 'Range', description: 'Run query over a range of time.' }, + { value: LokiQueryType.Range, label: 'Range', description: 'Run query over a range of time.' }, { - value: 'instant', + value: LokiQueryType.Instant, label: 'Instant', description: 'Run query against a single point in time. For this query, the "To" time is used.', }, + // { + // value: LokiQueryType.Stream, + // label: 'Stream', + // description: 'Run a query and keep sending results on an interval', + // }, ]; export const DEFAULT_RESOLUTION: SelectableValue = { @@ -42,21 +44,18 @@ const RESOLUTION_OPTIONS: Array> = [DEFAULT_RESOLUTION]. ); export function LokiOptionFields(props: LokiOptionFieldsProps) { - const { lineLimitValue, resolution, queryType, query, onRunQuery, runOnBlur, onChange } = props; + const { lineLimitValue, resolution, onRunQuery, runOnBlur, onChange } = props; + const query = props.query ?? {}; + let queryType = query.queryType ?? (query.instant ? LokiQueryType.Instant : LokiQueryType.Range); function onChangeQueryLimit(value: string) { const nextQuery = { ...query, maxLines: preprocessMaxLines(value) }; onChange(nextQuery); } - function onQueryTypeChange(value: LokiQueryType) { - let nextQuery; - if (value === 'instant') { - nextQuery = { ...query, instant: true, range: false }; - } else { - nextQuery = { ...query, instant: false, range: true }; - } - onChange(nextQuery); + function onQueryTypeChange(queryType: LokiQueryType) { + const { instant, range, ...rest } = query; + onChange({ ...rest, queryType }); } function preprocessMaxLines(value: string): number { @@ -155,6 +154,7 @@ export function LokiOptionFields(props: LokiOptionFieldsProps) { options={RESOLUTION_OPTIONS} value={resolution} aria-label="Select resolution" + menuShouldPortal /> diff --git a/public/app/plugins/datasource/loki/components/LokiQueryEditor.tsx b/public/app/plugins/datasource/loki/components/LokiQueryEditor.tsx index a2d0ad35516..5aa42a64dcb 100644 --- a/public/app/plugins/datasource/loki/components/LokiQueryEditor.tsx +++ b/public/app/plugins/datasource/loki/components/LokiQueryEditor.tsx @@ -51,7 +51,6 @@ export function LokiQueryEditor(props: LokiQueryEditorProps) { ExtraFieldElement={ <> } diff --git a/public/app/plugins/datasource/loki/components/__snapshots__/LokiQueryEditor.test.tsx.snap b/public/app/plugins/datasource/loki/components/__snapshots__/LokiQueryEditor.test.tsx.snap index 8b2822cfed3..2518d3318be 100644 --- a/public/app/plugins/datasource/loki/components/__snapshots__/LokiQueryEditor.test.tsx.snap +++ b/public/app/plugins/datasource/loki/components/__snapshots__/LokiQueryEditor.test.tsx.snap @@ -15,7 +15,6 @@ exports[`Render LokiQueryEditor with legend should render 1`] = ` "refId": "A", } } - queryType="range" resolution={1} runOnBlur={true} /> @@ -81,7 +80,6 @@ exports[`Render LokiQueryEditor with legend should update timerange 1`] = ` "refId": "A", } } - queryType="range" resolution={1} runOnBlur={true} /> diff --git a/public/app/plugins/datasource/loki/datasource.ts b/public/app/plugins/datasource/loki/datasource.ts index f345bf4c32f..537386a8cc3 100644 --- a/public/app/plugins/datasource/loki/datasource.ts +++ b/public/app/plugins/datasource/loki/datasource.ts @@ -49,6 +49,7 @@ import { addParsedLabelToQuery, queryHasPipeParser } from './query_utils'; import { LokiOptions, LokiQuery, + LokiQueryType, LokiRangeQueryRequest, LokiResultType, LokiStreamResponse, @@ -172,7 +173,7 @@ export class LokiDatasource }); for (const target of filteredTargets) { - if (target.instant) { + if (target.instant || target.queryType === LokiQueryType.Instant) { subQueries.push(this.runInstantQuery(target, options, filteredTargets.length)); } else { subQueries.push(this.runRangeQuery(target, options, filteredTargets.length)); @@ -647,6 +648,7 @@ export class LokiDatasource maxLines, instant, stepInterval, + queryType: instant ? LokiQueryType.Instant : LokiQueryType.Range, }; const { data } = instant ? await lastValueFrom(this.runInstantQuery(query, options as any)) diff --git a/public/app/plugins/datasource/loki/language_provider.test.ts b/public/app/plugins/datasource/loki/language_provider.test.ts index fe28721dbc6..70fdfd10f8f 100644 --- a/public/app/plugins/datasource/loki/language_provider.test.ts +++ b/public/app/plugins/datasource/loki/language_provider.test.ts @@ -6,6 +6,7 @@ import { TypeaheadInput } from '@grafana/ui'; import { makeMockLokiDatasource } from './mocks'; import LokiDatasource from './datasource'; import { AbstractLabelOperator } from '@grafana/data'; +import { LokiQueryType } from './types'; jest.mock('app/store/store', () => ({ store: { @@ -248,7 +249,7 @@ describe('Query imports', () => { it('returns empty queries', async () => { const instance = new LanguageProvider(datasource); const result = await instance.importFromAbstractQuery({ refId: 'bar', labelMatchers: [] }); - expect(result).toEqual({ refId: 'bar', expr: '', range: true }); + expect(result).toEqual({ refId: 'bar', expr: '', queryType: LokiQueryType.Range }); }); describe('exporting to abstract query', () => { diff --git a/public/app/plugins/datasource/loki/language_provider.ts b/public/app/plugins/datasource/loki/language_provider.ts index 9e425dc4085..fce76be1f9b 100644 --- a/public/app/plugins/datasource/loki/language_provider.ts +++ b/public/app/plugins/datasource/loki/language_provider.ts @@ -7,12 +7,12 @@ import { extractLabelMatchers, parseSelector, processLabels, - toPromLikeQuery, + toPromLikeExpr, } from 'app/plugins/datasource/prometheus/language_utils'; import syntax, { FUNCTIONS, PIPE_PARSERS, PIPE_OPERATORS } from './syntax'; // Types -import { LokiQuery } from './types'; +import { LokiQuery, LokiQueryType } from './types'; import { dateTime, AbsoluteTimeRange, LanguageProvider, HistoryItem, AbstractQuery } from '@grafana/data'; import LokiDatasource from './datasource'; @@ -332,7 +332,11 @@ export default class LokiLanguageProvider extends LanguageProvider { } importFromAbstractQuery(labelBasedQuery: AbstractQuery): LokiQuery { - return toPromLikeQuery(labelBasedQuery); + return { + refId: labelBasedQuery.refId, + expr: toPromLikeExpr(labelBasedQuery), + queryType: LokiQueryType.Range, + }; } exportToAbstractQuery(query: LokiQuery): AbstractQuery { diff --git a/public/app/plugins/datasource/loki/types.ts b/public/app/plugins/datasource/loki/types.ts index 68aa471b781..c654c78dc8e 100644 --- a/public/app/plugins/datasource/loki/types.ts +++ b/public/app/plugins/datasource/loki/types.ts @@ -22,7 +22,14 @@ export enum LokiResultType { Matrix = 'matrix', } +export enum LokiQueryType { + Range = 'range', + Instant = 'instant', + // Stream = 'stream', +} + export interface LokiQuery extends DataQuery { + queryType?: LokiQueryType; expr: string; query?: string; format?: string; @@ -31,9 +38,13 @@ export interface LokiQuery extends DataQuery { valueWithRefId?: boolean; maxLines?: number; resolution?: number; + volumeQuery?: boolean; // Used in range queries + + /* @deprecated now use queryType */ range?: boolean; + + /* @deprecated now use queryType */ instant?: boolean; - volumeQuery?: boolean; } export interface LokiOptions extends DataSourceJsonData { diff --git a/public/app/plugins/datasource/prometheus/language_utils.ts b/public/app/plugins/datasource/prometheus/language_utils.ts index f886f62ff6b..a470cca85f6 100644 --- a/public/app/plugins/datasource/prometheus/language_utils.ts +++ b/public/app/plugins/datasource/prometheus/language_utils.ts @@ -274,7 +274,7 @@ const ToPromLikeMap: Record = invert(FromPromLike string >; -export function toPromLikeQuery(labelBasedQuery: AbstractQuery): PromLikeQuery { +export function toPromLikeExpr(labelBasedQuery: AbstractQuery): string { const expr = labelBasedQuery.labelMatchers .map((selector: AbstractLabelMatcher) => { const operator = ToPromLikeMap[selector.operator]; @@ -287,9 +287,13 @@ export function toPromLikeQuery(labelBasedQuery: AbstractQuery): PromLikeQuery { .filter((e: string) => e !== '') .join(', '); + return expr ? `{${expr}}` : ''; +} + +export function toPromLikeQuery(labelBasedQuery: AbstractQuery): PromLikeQuery { return { refId: labelBasedQuery.refId, - expr: expr ? `{${expr}}` : '', + expr: toPromLikeExpr(labelBasedQuery), range: true, }; }