From bc425a79930bbde1f28700c586a5b7c05f557efe Mon Sep 17 00:00:00 2001 From: Ivana Huckova <30407135+ivanahuckova@users.noreply.github.com> Date: Mon, 30 Jun 2025 16:41:00 +0200 Subject: [PATCH] Loki: Remove experimental lokiQuerySplittingConfig (#107298) * Loki: Remove experimental lokiQuerySplittingConfig * Remove unused imports --- .../src/types/featureToggles.gen.ts | 4 - pkg/services/featuremgmt/registry.go | 7 -- pkg/services/featuremgmt/toggles_gen.csv | 1 - pkg/services/featuremgmt/toggles_gen.go | 4 - pkg/services/featuremgmt/toggles_gen.json | 3 +- .../datasource/loki/querySplitting.test.ts | 84 ------------------- .../plugins/datasource/loki/querySplitting.ts | 56 +++++-------- .../components/LokiQueryBuilderOptions.tsx | 40 +-------- public/app/plugins/datasource/loki/types.ts | 6 -- 9 files changed, 27 insertions(+), 178 deletions(-) diff --git a/packages/grafana-data/src/types/featureToggles.gen.ts b/packages/grafana-data/src/types/featureToggles.gen.ts index 6350852823a..c94a3165b08 100644 --- a/packages/grafana-data/src/types/featureToggles.gen.ts +++ b/packages/grafana-data/src/types/featureToggles.gen.ts @@ -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; diff --git a/pkg/services/featuremgmt/registry.go b/pkg/services/featuremgmt/registry.go index a92e51294b5..85fc598fad4 100644 --- a/pkg/services/featuremgmt/registry.go +++ b/pkg/services/featuremgmt/registry.go @@ -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", diff --git a/pkg/services/featuremgmt/toggles_gen.csv b/pkg/services/featuremgmt/toggles_gen.csv index b9106003778..2278cb1fb50 100644 --- a/pkg/services/featuremgmt/toggles_gen.csv +++ b/pkg/services/featuremgmt/toggles_gen.csv @@ -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 diff --git a/pkg/services/featuremgmt/toggles_gen.go b/pkg/services/featuremgmt/toggles_gen.go index e7e939c6885..fbd6e7ab88a 100644 --- a/pkg/services/featuremgmt/toggles_gen.go +++ b/pkg/services/featuremgmt/toggles_gen.go @@ -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" diff --git a/pkg/services/featuremgmt/toggles_gen.json b/pkg/services/featuremgmt/toggles_gen.json index aa066802f55..dda8e2005c4 100644 --- a/pkg/services/featuremgmt/toggles_gen.json +++ b/pkg/services/featuremgmt/toggles_gen.json @@ -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", diff --git a/public/app/plugins/datasource/loki/querySplitting.test.ts b/public/app/plugins/datasource/loki/querySplitting.test.ts index a017f6ba866..9394adf938b 100644 --- a/public/app/plugins/datasource/loki/querySplitting.test.ts +++ b/public/app/plugins/datasource/loki/querySplitting.test.ts @@ -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; - 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; - 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; - 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; - 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'), diff --git a/public/app/plugins/datasource/loki/querySplitting.ts b/public/app/plugins/datasource/loki/querySplitting.ts index e20b38151c1..069ed4e7b90 100644 --- a/public/app/plugins/datasource/loki/querySplitting.ts +++ b/public/app/plugins/datasource/loki/querySplitting.ts @@ -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)), - }; - - if (direction === LokiQueryDirection.Forward) { - groupedRequest.partition.reverse(); - } + 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), + }; - 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) { diff --git a/public/app/plugins/datasource/loki/querybuilder/components/LokiQueryBuilderOptions.tsx b/public/app/plugins/datasource/loki/querybuilder/components/LokiQueryBuilderOptions.tsx index d04e9fc42f6..8328bc42b86 100644 --- a/public/app/plugins/datasource/loki/querybuilder/components/LokiQueryBuilderOptions.tsx +++ b/public/app/plugins/datasource/loki/querybuilder/components/LokiQueryBuilderOptions.tsx @@ -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( ({ 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( [onChange, onRunQuery, query] ); - const onChunkRangeChange = (evt: React.FormEvent) => { - const value = evt.currentTarget.value; - if (!isValidDuration(value)) { - setSplitDurationValid(false); - return; - } - setSplitDurationValid(true); - onChange({ ...query, splitDuration: value }); - onRunQuery(); - }; - const onLegendFormatChanged = (evt: React.FormEvent) => { onChange({ ...query, legendFormat: evt.currentTarget.value }); onRunQuery(); @@ -214,21 +195,6 @@ export const LokiQueryBuilderOptions = React.memo( )} - {config.featureToggles.lokiQuerySplittingConfig && config.featureToggles.lokiQuerySplitting && ( - - - - )} ); diff --git a/public/app/plugins/datasource/loki/types.ts b/public/app/plugins/datasource/loki/types.ts index 0d65f2bd2cb..ae650931390 100644 --- a/public/app/plugins/datasource/loki/types.ts +++ b/public/app/plugins/datasource/loki/types.ts @@ -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 {