Loki: Remove`TimeSrv` dependency (#78642)

* Loki: Remove  dependency

* Update loadUnwrapOptions
pull/71168/head^2
Ivana Huckova 2 years ago committed by GitHub
parent f7ace22285
commit b3deef8f4b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 12
      public/app/plugins/datasource/loki/LanguageProvider.test.ts
  2. 2
      public/app/plugins/datasource/loki/LanguageProvider.ts
  3. 34
      public/app/plugins/datasource/loki/datasource.test.ts
  4. 22
      public/app/plugins/datasource/loki/datasource.ts
  5. 7
      public/app/plugins/datasource/loki/querybuilder/components/LokiQueryBuilder.tsx
  6. 10
      public/app/plugins/datasource/loki/querybuilder/components/UnwrapParamEditor.tsx
  7. 5
      public/app/plugins/datasource/prometheus/querybuilder/shared/OperationEditor.tsx
  8. 5
      public/app/plugins/datasource/prometheus/querybuilder/shared/OperationList.tsx
  9. 3
      public/app/plugins/datasource/prometheus/querybuilder/shared/types.ts

@ -407,7 +407,11 @@ describe('Query imports', () => {
maxLines: DEFAULT_MAX_LINES_SAMPLE,
refId: 'data-samples',
},
undefined
// mocked default time range
expect.objectContaining({
from: 0,
to: 1,
})
);
});
@ -428,7 +432,11 @@ describe('Query imports', () => {
maxLines: 5,
refId: 'data-samples',
},
undefined
// mocked default time range
expect.objectContaining({
from: 0,
to: 1,
})
);
});

@ -267,7 +267,7 @@ export default class LokiLanguageProvider extends LanguageProvider {
refId: 'data-samples',
maxLines: options?.maxLines || DEFAULT_MAX_LINES_SAMPLE,
},
options?.timeRange
options?.timeRange ?? this.getDefaultTimeRange()
);
if (!series.length) {

@ -1474,26 +1474,26 @@ describe('LokiDatasource', () => {
});
it('ignores invalid queries', () => {
const spy = jest.spyOn(ds, 'query');
ds.getDataSamples({ expr: 'not a query', refId: 'A' });
ds.getDataSamples({ expr: 'not a query', refId: 'A' }, mockTimeRange);
expect(spy).not.toHaveBeenCalled();
});
it('ignores metric queries', () => {
const spy = jest.spyOn(ds, 'query');
ds.getDataSamples({ expr: 'count_over_time({a="b"}[1m])', refId: 'A' });
ds.getDataSamples({ expr: 'count_over_time({a="b"}[1m])', refId: 'A' }, mockTimeRange);
expect(spy).not.toHaveBeenCalled();
});
it('uses the current interval in the request', () => {
const spy = jest.spyOn(ds, 'query').mockImplementation(() => of({} as DataQueryResponse));
ds.getDataSamples({ expr: '{job="bar"}', refId: 'A' });
ds.getDataSamples({ expr: '{job="bar"}', refId: 'A' }, mockTimeRange);
expect(spy).toHaveBeenCalledWith(
expect.objectContaining({
range: ds.getTimeRange(),
range: mockTimeRange,
})
);
});
it('hides the request from the inspector', () => {
const spy = jest.spyOn(ds, 'query').mockImplementation(() => of({} as DataQueryResponse));
ds.getDataSamples({ expr: '{job="bar"}', refId: 'A' });
ds.getDataSamples({ expr: '{job="bar"}', refId: 'A' }, mockTimeRange);
expect(spy).toHaveBeenCalledWith(
expect.objectContaining({
hideFromInspector: true,
@ -1503,7 +1503,7 @@ describe('LokiDatasource', () => {
});
it('sets the supporting query type in the request', () => {
const spy = jest.spyOn(ds, 'query').mockImplementation(() => of({} as DataQueryResponse));
ds.getDataSamples({ expr: '{job="bar"}', refId: 'A' });
ds.getDataSamples({ expr: '{job="bar"}', refId: 'A' }, mockTimeRange);
expect(spy).toHaveBeenCalledWith(
expect.objectContaining({
targets: [expect.objectContaining({ supportingQueryType: SupportingQueryType.DataSample })],
@ -1828,18 +1828,18 @@ describe('makeStatsRequest', () => {
});
});
describe('getTimeRange*()', () => {
it('exposes the current time range', () => {
describe('getTimeRangeParams()', () => {
it('turns time range into a Loki range parameters', () => {
const ds = createLokiDatasource();
const timeRange = ds.getTimeRange();
expect(timeRange.from).toBeDefined();
expect(timeRange.to).toBeDefined();
});
it('exposes time range as params', () => {
const ds = createLokiDatasource();
const params = ds.getTimeRangeParams();
const range = {
from: dateTime(1524650400000),
to: dateTime(1524654000000),
raw: {
from: 'now-1h',
to: 'now',
},
};
const params = ds.getTimeRangeParams(range);
// Returns a very big integer, so we stringify it for the assertion
expect(JSON.stringify(params)).toEqual('{"start":1524650400000000000,"end":1524654000000000000}');

@ -45,7 +45,6 @@ import {
import { Duration } from '@grafana/lezer-logql';
import { BackendSrvRequest, config, DataSourceWithBackend, getTemplateSrv, TemplateSrv } from '@grafana/runtime';
import { DataQuery } from '@grafana/schema';
import { getTimeSrv, TimeSrv } from 'app/features/dashboard/services/TimeSrv';
import { queryLogsSample, queryLogsVolume } from '../../../features/logs/logsModel';
import { getLogLevelFromKey } from '../../../features/logs/utils';
@ -152,8 +151,7 @@ export class LokiDatasource
constructor(
private instanceSettings: DataSourceInstanceSettings<LokiOptions>,
private readonly templateSrv: TemplateSrv = getTemplateSrv(),
private readonly timeSrv: TimeSrv = getTimeSrv()
private readonly templateSrv: TemplateSrv = getTemplateSrv()
) {
super(instanceSettings);
@ -455,21 +453,12 @@ export class LokiDatasource
return query.expr;
}
/**
* Retrieve the current time range.
* @returns The current time range as provided by the timeSrv.
*/
getTimeRange() {
return this.timeSrv.timeRange();
}
/**
* Given a time range, returns it as Loki parameters.
* @returns An object containing the start and end times in nanoseconds since the Unix epoch.
*/
getTimeRangeParams(timeRange?: TimeRange) {
const range = timeRange ?? this.getTimeRange();
return { start: range.from.valueOf() * NS_IN_MS, end: range.to.valueOf() * NS_IN_MS };
getTimeRangeParams(timeRange: TimeRange) {
return { start: timeRange.from.valueOf() * NS_IN_MS, end: timeRange.to.valueOf() * NS_IN_MS };
}
/**
@ -734,7 +723,7 @@ export class LokiDatasource
* Currently, it works for logs data only.
* @returns A Promise that resolves to an array of DataFrames containing data samples.
*/
async getDataSamples(query: LokiQuery, timeRange?: TimeRange): Promise<DataFrame[]> {
async getDataSamples(query: LokiQuery, timeRange: TimeRange): Promise<DataFrame[]> {
// Currently works only for logs sample
if (!isLogsQuery(query.expr) || isQueryWithError(this.interpolateString(query.expr, placeHolderScopedVars))) {
return [];
@ -748,8 +737,7 @@ export class LokiDatasource
supportingQueryType: SupportingQueryType.DataSample,
};
const range = timeRange ?? this.getTimeRange();
const request = makeRequest(lokiLogsQuery, range, CoreApp.Unknown, REF_ID_DATA_SAMPLES, true);
const request = makeRequest(lokiLogsQuery, timeRange, CoreApp.Unknown, REF_ID_DATA_SAMPLES, true);
return await lastValueFrom(this.query(request).pipe(switchMap((res) => of(res.data))));
}

@ -99,13 +99,14 @@ export const LokiQueryBuilder = React.memo<Props>(
useEffect(() => {
const onGetSampleData = async () => {
const lokiQuery = { expr: lokiQueryModeller.renderQuery(query), refId: 'data-samples' };
const series = await datasource.getDataSamples(lokiQuery);
const sampleData = { series, state: LoadingState.Done, timeRange: getDefaultTimeRange() };
const range = timeRange ?? getDefaultTimeRange();
const series = await datasource.getDataSamples(lokiQuery, range);
const sampleData = { series, state: LoadingState.Done, timeRange: range };
setSampleData(sampleData);
};
onGetSampleData().catch(console.error);
}, [datasource, query]);
}, [datasource, query, timeRange]);
const lang = { grammar: logqlGrammar, name: 'logql' };
return (

@ -1,6 +1,6 @@
import React, { useState } from 'react';
import { SelectableValue, toOption } from '@grafana/data';
import { SelectableValue, getDefaultTimeRange, toOption } from '@grafana/data';
import { Select } from '@grafana/ui';
import { getOperationParamId } from '../../../prometheus/querybuilder/shared/operationUtils';
@ -19,6 +19,7 @@ export function UnwrapParamEditor({
value,
query,
datasource,
timeRange,
}: QueryBuilderOperationParamEditorProps) {
const [state, setState] = useState<{
options?: Array<SelectableValue<string>>;
@ -32,7 +33,7 @@ export function UnwrapParamEditor({
// This check is always true, we do it to make typescript happy
if (datasource instanceof LokiDatasource) {
setState({ isLoading: true });
const options = await loadUnwrapOptions(query, datasource);
const options = await loadUnwrapOptions(query, datasource, timeRange);
setState({ options, isLoading: undefined });
}
}}
@ -53,7 +54,8 @@ export function UnwrapParamEditor({
async function loadUnwrapOptions(
query: LokiVisualQuery,
datasource: LokiDatasource
datasource: LokiDatasource,
timeRange = getDefaultTimeRange()
): Promise<Array<SelectableValue<string>>> {
const queryExpr = lokiQueryModeller.renderQuery(query);
const logExpr = getLogQueryFromMetricsQuery(queryExpr);
@ -61,7 +63,7 @@ async function loadUnwrapOptions(
return [];
}
const samples = await datasource.getDataSamples({ expr: logExpr, refId: 'unwrap_samples' });
const samples = await datasource.getDataSamples({ expr: logExpr, refId: 'unwrap_samples' }, timeRange);
const unwrapLabels = extractUnwrapLabelKeysFromDataFrame(samples[0]);
const labelOptions = unwrapLabels.map((label) => ({

@ -2,7 +2,7 @@ import { css, cx } from '@emotion/css';
import React, { useEffect, useId, useState } from 'react';
import { Draggable } from 'react-beautiful-dnd';
import { DataSourceApi, GrafanaTheme2 } from '@grafana/data';
import { DataSourceApi, GrafanaTheme2, TimeRange } from '@grafana/data';
import { Button, Icon, InlineField, Tooltip, useTheme2, Stack } from '@grafana/ui';
import { isConflictingFilter } from 'app/plugins/datasource/loki/querybuilder/operationUtils';
import { LokiOperationId } from 'app/plugins/datasource/loki/querybuilder/types';
@ -29,6 +29,7 @@ export interface Props {
onRunQuery: () => void;
flash?: boolean;
highlight?: boolean;
timeRange?: TimeRange;
}
export function OperationEditor({
@ -42,6 +43,7 @@ export function OperationEditor({
datasource,
flash,
highlight,
timeRange,
}: Props) {
const def = queryModeller.getOperationDef(operation.id);
const shouldFlash = useFlash(flash);
@ -106,6 +108,7 @@ export function OperationEditor({
onRunQuery={onRunQuery}
query={query}
datasource={datasource}
timeRange={timeRange}
/>
{paramDef.restParam && (operation.params.length > def.params.length || paramDef.optional) && (
<Button

@ -3,7 +3,7 @@ import React, { useState } from 'react';
import { DragDropContext, Droppable, DropResult } from 'react-beautiful-dnd';
import { useMountedState, usePrevious } from 'react-use';
import { DataSourceApi, GrafanaTheme2 } from '@grafana/data';
import { DataSourceApi, GrafanaTheme2, TimeRange } from '@grafana/data';
import { Button, Cascader, CascaderOption, useStyles2, Stack } from '@grafana/ui';
import { OperationEditor } from './OperationEditor';
@ -17,6 +17,7 @@ export interface Props<T extends QueryWithOperations> {
queryModeller: VisualQueryModeller;
explainMode?: boolean;
highlightedOp?: QueryBuilderOperation;
timeRange?: TimeRange;
}
export function OperationList<T extends QueryWithOperations>({
@ -26,6 +27,7 @@ export function OperationList<T extends QueryWithOperations>({
onChange,
onRunQuery,
highlightedOp,
timeRange,
}: Props<T>) {
const styles = useStyles2(getStyles);
const { operations } = query;
@ -104,6 +106,7 @@ export function OperationList<T extends QueryWithOperations>({
onRunQuery={onRunQuery}
flash={opsToHighlight[index]}
highlight={highlightedOp === op}
timeRange={timeRange}
/>
);
})}

@ -4,7 +4,7 @@
import { ComponentType } from 'react';
import { DataSourceApi, RegistryItem, SelectableValue } from '@grafana/data';
import { DataSourceApi, RegistryItem, SelectableValue, TimeRange } from '@grafana/data';
export interface QueryBuilderLabelFilter {
label: string;
@ -92,6 +92,7 @@ export interface QueryBuilderOperationParamEditorProps {
operationId: string;
query: any;
datasource: DataSourceApi;
timeRange?: TimeRange;
onChange: (index: number, value: QueryBuilderOperationParamValue) => void;
onRunQuery: () => void;
}

Loading…
Cancel
Save