Loki: Remove experimental lokiQuerySplittingConfig (#107298)
* Loki: Remove experimental lokiQuerySplittingConfig * Remove unused imports
This commit is contained in:
@@ -107,10 +107,6 @@ export interface FeatureToggles {
|
||||
*/
|
||||
lokiQuerySplitting?: boolean;
|
||||
/**
|
||||
* Give users the option to configure split durations for Loki queries
|
||||
*/
|
||||
lokiQuerySplittingConfig?: boolean;
|
||||
/**
|
||||
* Support overriding cookie preferences per user
|
||||
*/
|
||||
individualCookiePreferences?: boolean;
|
||||
|
||||
@@ -163,13 +163,6 @@ var (
|
||||
Expression: "true", // turned on by default
|
||||
AllowSelfServe: true,
|
||||
},
|
||||
{
|
||||
Name: "lokiQuerySplittingConfig",
|
||||
Description: "Give users the option to configure split durations for Loki queries",
|
||||
Stage: FeatureStageExperimental,
|
||||
FrontendOnly: true,
|
||||
Owner: grafanaObservabilityLogsSquad,
|
||||
},
|
||||
{
|
||||
Name: "individualCookiePreferences",
|
||||
Description: "Support overriding cookie preferences per user",
|
||||
|
||||
@@ -19,7 +19,6 @@ editPanelCSVDragAndDrop,experimental,@grafana/dataviz-squad,false,false,true
|
||||
logsContextDatasourceUi,GA,@grafana/observability-logs,false,false,true
|
||||
lokiShardSplitting,experimental,@grafana/observability-logs,false,false,true
|
||||
lokiQuerySplitting,GA,@grafana/observability-logs,false,false,true
|
||||
lokiQuerySplittingConfig,experimental,@grafana/observability-logs,false,false,true
|
||||
individualCookiePreferences,experimental,@grafana/grafana-backend-group,false,false,false
|
||||
influxdbBackendMigration,GA,@grafana/partner-datasources,false,false,true
|
||||
influxqlStreamingParser,experimental,@grafana/partner-datasources,false,false,false
|
||||
|
||||
|
@@ -87,10 +87,6 @@ const (
|
||||
// Split large interval queries into subqueries with smaller time intervals
|
||||
FlagLokiQuerySplitting = "lokiQuerySplitting"
|
||||
|
||||
// FlagLokiQuerySplittingConfig
|
||||
// Give users the option to configure split durations for Loki queries
|
||||
FlagLokiQuerySplittingConfig = "lokiQuerySplittingConfig"
|
||||
|
||||
// FlagIndividualCookiePreferences
|
||||
// Support overriding cookie preferences per user
|
||||
FlagIndividualCookiePreferences = "individualCookiePreferences"
|
||||
|
||||
@@ -1889,7 +1889,8 @@
|
||||
"metadata": {
|
||||
"name": "lokiQuerySplittingConfig",
|
||||
"resourceVersion": "1750434297879",
|
||||
"creationTimestamp": "2023-03-20T15:51:36Z"
|
||||
"creationTimestamp": "2023-03-20T15:51:36Z",
|
||||
"deletionTimestamp": "2025-06-27T09:32:43Z"
|
||||
},
|
||||
"spec": {
|
||||
"description": "Give users the option to configure split durations for Loki queries",
|
||||
|
||||
@@ -442,90 +442,6 @@ describe('runSplitQuery()', () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe('Splitting targets based on splitDuration', () => {
|
||||
const range1h = {
|
||||
from: dateTime('2023-02-08T05:00:00.000Z'),
|
||||
to: dateTime('2023-02-08T06:00:00.000Z'),
|
||||
raw: {
|
||||
from: dateTime('2023-02-08T05:00:00.000Z'),
|
||||
to: dateTime('2023-02-08T06:00:00.000Z'),
|
||||
},
|
||||
};
|
||||
beforeEach(() => {
|
||||
jest.spyOn(datasource, 'runQuery').mockReturnValue(of({ data: [], refId: 'A' }));
|
||||
});
|
||||
test('with 30m splitDuration runs 2 queries', async () => {
|
||||
const request = {
|
||||
targets: [{ expr: '{a="b"}', refId: 'A', splitDuration: '30m' }],
|
||||
range: range1h,
|
||||
} as DataQueryRequest<LokiQuery>;
|
||||
await expect(runSplitQuery(datasource, request)).toEmitValuesWith(() => {
|
||||
expect(datasource.runQuery).toHaveBeenCalledTimes(2);
|
||||
});
|
||||
});
|
||||
test('with 1h splitDuration runs 1 queries', async () => {
|
||||
const request = {
|
||||
targets: [{ expr: '{a="b"}', refId: 'A', splitDuration: '1h' }],
|
||||
range: range1h,
|
||||
} as DataQueryRequest<LokiQuery>;
|
||||
await expect(runSplitQuery(datasource, request)).toEmitValuesWith(() => {
|
||||
expect(datasource.runQuery).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
});
|
||||
test('with 1h splitDuration and 2 targets runs 1 queries', async () => {
|
||||
const request = {
|
||||
targets: [
|
||||
{ expr: '{a="b"}', refId: 'A', splitDuration: '1h' },
|
||||
{ expr: '{a="b"}', refId: 'B', splitDuration: '1h' },
|
||||
],
|
||||
range: range1h,
|
||||
} as DataQueryRequest<LokiQuery>;
|
||||
await expect(runSplitQuery(datasource, request)).toEmitValuesWith(() => {
|
||||
expect(datasource.runQuery).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
});
|
||||
test('with 1h/30m splitDuration and 2 targets runs 3 queries', async () => {
|
||||
const request = {
|
||||
targets: [
|
||||
{ expr: '{a="b"}', refId: 'A', splitDuration: '1h' },
|
||||
{ expr: '{a="b"}', refId: 'B', splitDuration: '30m' },
|
||||
],
|
||||
range: range1h,
|
||||
} as DataQueryRequest<LokiQuery>;
|
||||
await expect(runSplitQuery(datasource, request)).toEmitValuesWith(() => {
|
||||
// 2 x 30m + 1 x 1h
|
||||
expect(datasource.runQuery).toHaveBeenCalledTimes(3);
|
||||
});
|
||||
});
|
||||
test('with mixed splitDuration runs the expected amount of queries', async () => {
|
||||
const request = createRequest(
|
||||
[
|
||||
{ expr: 'count_over_time({c="d"}[1m])', refId: 'A', splitDuration: '15m' },
|
||||
{ expr: '{a="b"}', refId: 'B', splitDuration: '15m' },
|
||||
{ expr: '{a="b"}', refId: 'C', splitDuration: '1h' },
|
||||
],
|
||||
{ range: range1h }
|
||||
);
|
||||
await expect(runSplitQuery(datasource, request)).toEmitValuesWith(() => {
|
||||
// 4 * 15m + 4 * 15m + 1 * 1h
|
||||
expect(datasource.runQuery).toHaveBeenCalledTimes(9);
|
||||
});
|
||||
});
|
||||
test('with 1h/30m splitDuration and 1 log and 2 metric target runs 3 queries', async () => {
|
||||
const request = createRequest(
|
||||
[
|
||||
{ expr: '{a="b"}', refId: 'A', splitDuration: '1h' },
|
||||
{ expr: 'count_over_time({c="d"}[1m])', refId: 'C', splitDuration: '30m' },
|
||||
],
|
||||
{ range: range1h }
|
||||
);
|
||||
await expect(runSplitQuery(datasource, request)).toEmitValuesWith(() => {
|
||||
// 2 x 30m + 1 x 1h
|
||||
expect(datasource.runQuery).toHaveBeenCalledTimes(3);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('Splitting targets based on resolution', () => {
|
||||
const range1d = {
|
||||
from: dateTime('2023-02-08T05:00:00.000Z'),
|
||||
|
||||
@@ -8,8 +8,6 @@ import {
|
||||
DataQueryResponse,
|
||||
DataTopic,
|
||||
dateTime,
|
||||
durationToMilliseconds,
|
||||
parseDuration,
|
||||
rangeUtil,
|
||||
TimeRange,
|
||||
LoadingState,
|
||||
@@ -307,45 +305,35 @@ export function runSplitQuery(
|
||||
const requests: LokiGroupedRequest[] = [];
|
||||
|
||||
for (const direction in directionPartitionedLogQueries) {
|
||||
const rangePartitionedLogQueries = groupBy(directionPartitionedLogQueries[direction], (query) =>
|
||||
query.splitDuration ? durationToMilliseconds(parseDuration(query.splitDuration)) : oneDayMs
|
||||
);
|
||||
for (const [chunkRangeMs, queries] of Object.entries(rangePartitionedLogQueries)) {
|
||||
const resolutionPartition = groupBy(queries, (query) => query.resolution || 1);
|
||||
for (const resolution in resolutionPartition) {
|
||||
const groupedRequest = {
|
||||
request: { ...request, targets: resolutionPartition[resolution] },
|
||||
partition: partitionTimeRange(true, request.range, request.intervalMs, Number(chunkRangeMs)),
|
||||
};
|
||||
const queries = directionPartitionedLogQueries[direction];
|
||||
const resolutionPartition = groupBy(queries, (query) => query.resolution || 1);
|
||||
for (const resolution in resolutionPartition) {
|
||||
const groupedRequest = {
|
||||
request: { ...request, targets: resolutionPartition[resolution] },
|
||||
partition: partitionTimeRange(true, request.range, request.intervalMs, oneDayMs),
|
||||
};
|
||||
|
||||
if (direction === LokiQueryDirection.Forward) {
|
||||
groupedRequest.partition.reverse();
|
||||
}
|
||||
|
||||
requests.push(groupedRequest);
|
||||
if (direction === LokiQueryDirection.Forward) {
|
||||
groupedRequest.partition.reverse();
|
||||
}
|
||||
|
||||
requests.push(groupedRequest);
|
||||
}
|
||||
}
|
||||
|
||||
const rangePartitionedMetricQueries = groupBy(metricQueries, (query) =>
|
||||
query.splitDuration ? durationToMilliseconds(parseDuration(query.splitDuration)) : oneDayMs
|
||||
const stepMsPartition = groupBy(metricQueries, (query) =>
|
||||
calculateStep(request.intervalMs, request.range, query.resolution || 1, query.step)
|
||||
);
|
||||
|
||||
for (const [chunkRangeMs, queries] of Object.entries(rangePartitionedMetricQueries)) {
|
||||
const stepMsPartition = groupBy(queries, (query) =>
|
||||
calculateStep(request.intervalMs, request.range, query.resolution || 1, query.step)
|
||||
);
|
||||
|
||||
for (const stepMs in stepMsPartition) {
|
||||
const targets = stepMsPartition[stepMs].map((q) => {
|
||||
const { maxLines, ...query } = q;
|
||||
return query;
|
||||
});
|
||||
requests.push({
|
||||
request: { ...request, targets },
|
||||
partition: partitionTimeRange(false, request.range, Number(stepMs), Number(chunkRangeMs)),
|
||||
});
|
||||
}
|
||||
for (const stepMs in stepMsPartition) {
|
||||
const targets = stepMsPartition[stepMs].map((q) => {
|
||||
const { maxLines, ...query } = q;
|
||||
return query;
|
||||
});
|
||||
requests.push({
|
||||
request: { ...request, targets },
|
||||
partition: partitionTimeRange(false, request.range, Number(stepMs), oneDayMs),
|
||||
});
|
||||
}
|
||||
|
||||
if (nonSplittingQueries.length) {
|
||||
|
||||
+3
-37
@@ -1,17 +1,10 @@
|
||||
import { trim } from 'lodash';
|
||||
import { useCallback, useEffect, useMemo, useState } from 'react';
|
||||
import { useCallback, useEffect, useMemo } from 'react';
|
||||
import * as React from 'react';
|
||||
|
||||
import {
|
||||
CoreApp,
|
||||
isValidDuration,
|
||||
isValidGrafanaDuration,
|
||||
LogSortOrderChangeEvent,
|
||||
LogsSortOrder,
|
||||
store,
|
||||
} from '@grafana/data';
|
||||
import { CoreApp, isValidGrafanaDuration, LogSortOrderChangeEvent, LogsSortOrder, store } from '@grafana/data';
|
||||
import { EditorField, EditorRow, QueryOptionGroup } from '@grafana/plugin-ui';
|
||||
import { config, getAppEvents } from '@grafana/runtime';
|
||||
import { getAppEvents } from '@grafana/runtime';
|
||||
import { AutoSizeInput, RadioButtonGroup } from '@grafana/ui';
|
||||
|
||||
import {
|
||||
@@ -36,7 +29,6 @@ export interface Props {
|
||||
|
||||
export const LokiQueryBuilderOptions = React.memo<Props>(
|
||||
({ app, query, onChange, onRunQuery, queryStats, datasource }) => {
|
||||
const [splitDurationValid, setSplitDurationValid] = useState(true);
|
||||
const maxLines = datasource.maxLines;
|
||||
|
||||
useEffect(() => {
|
||||
@@ -71,17 +63,6 @@ export const LokiQueryBuilderOptions = React.memo<Props>(
|
||||
[onChange, onRunQuery, query]
|
||||
);
|
||||
|
||||
const onChunkRangeChange = (evt: React.FormEvent<HTMLInputElement>) => {
|
||||
const value = evt.currentTarget.value;
|
||||
if (!isValidDuration(value)) {
|
||||
setSplitDurationValid(false);
|
||||
return;
|
||||
}
|
||||
setSplitDurationValid(true);
|
||||
onChange({ ...query, splitDuration: value });
|
||||
onRunQuery();
|
||||
};
|
||||
|
||||
const onLegendFormatChanged = (evt: React.FormEvent<HTMLInputElement>) => {
|
||||
onChange({ ...query, legendFormat: evt.currentTarget.value });
|
||||
onRunQuery();
|
||||
@@ -214,21 +195,6 @@ export const LokiQueryBuilderOptions = React.memo<Props>(
|
||||
</EditorField>
|
||||
</>
|
||||
)}
|
||||
{config.featureToggles.lokiQuerySplittingConfig && config.featureToggles.lokiQuerySplitting && (
|
||||
<EditorField
|
||||
label="Split Duration"
|
||||
tooltip="Defines the duration of a single query when query splitting is enabled."
|
||||
>
|
||||
<AutoSizeInput
|
||||
minWidth={14}
|
||||
type="string"
|
||||
min={0}
|
||||
defaultValue={query.splitDuration ?? '1d'}
|
||||
onCommitChange={onChunkRangeChange}
|
||||
invalid={!splitDurationValid}
|
||||
/>
|
||||
</EditorField>
|
||||
)}
|
||||
</QueryOptionGroup>
|
||||
</EditorRow>
|
||||
);
|
||||
|
||||
@@ -30,12 +30,6 @@ export interface LokiQuery extends LokiQueryFromSchema {
|
||||
// the temporary fix (until this gets improved in the codegen), is to
|
||||
// override it here
|
||||
queryType?: LokiQueryType;
|
||||
|
||||
/**
|
||||
* This is a property for the experimental query splitting feature.
|
||||
* @experimental
|
||||
*/
|
||||
splitDuration?: string;
|
||||
}
|
||||
|
||||
export interface LokiOptions extends DataSourceJsonData {
|
||||
|
||||
Reference in New Issue
Block a user