Loki: Remove experimental predefined operations (#107289)

* Loki: Remove experimental predefined operations

* Fix lint
This commit is contained in:
Ivana Huckova 2025-06-30 16:08:36 +02:00 committed by GitHub
parent 7f2aed42a0
commit cc542f2b91
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
14 changed files with 12 additions and 133 deletions

View File

@ -166,10 +166,6 @@ export interface FeatureToggles {
*/ */
extraThemes?: boolean; extraThemes?: boolean;
/** /**
* Adds predefined query operations to Loki query editor
*/
lokiPredefinedOperations?: boolean;
/**
* Enables the plugins frontend sandbox * Enables the plugins frontend sandbox
*/ */
pluginsFrontendSandbox?: boolean; pluginsFrontendSandbox?: boolean;

View File

@ -262,13 +262,6 @@ var (
Stage: FeatureStageExperimental, Stage: FeatureStageExperimental,
Owner: grafanaFrontendPlatformSquad, Owner: grafanaFrontendPlatformSquad,
}, },
{
Name: "lokiPredefinedOperations",
Description: "Adds predefined query operations to Loki query editor",
FrontendOnly: true,
Stage: FeatureStageExperimental,
Owner: grafanaObservabilityLogsSquad,
},
{ {
Name: "pluginsFrontendSandbox", Name: "pluginsFrontendSandbox",
Description: "Enables the plugins frontend sandbox", Description: "Enables the plugins frontend sandbox",

View File

@ -33,7 +33,6 @@ refactorVariablesTimeRange,preview,@grafana/dashboards-squad,false,false,false
faroDatasourceSelector,preview,@grafana/app-o11y,false,false,true faroDatasourceSelector,preview,@grafana/app-o11y,false,false,true
enableDatagridEditing,preview,@grafana/dataviz-squad,false,false,true enableDatagridEditing,preview,@grafana/dataviz-squad,false,false,true
extraThemes,experimental,@grafana/grafana-frontend-platform,false,false,true extraThemes,experimental,@grafana/grafana-frontend-platform,false,false,true
lokiPredefinedOperations,experimental,@grafana/observability-logs,false,false,true
pluginsFrontendSandbox,privatePreview,@grafana/plugins-platform-backend,false,false,false pluginsFrontendSandbox,privatePreview,@grafana/plugins-platform-backend,false,false,false
pluginsDetailsRightPanel,GA,@grafana/plugins-platform-backend,false,false,true pluginsDetailsRightPanel,GA,@grafana/plugins-platform-backend,false,false,true
sqlDatasourceDatabaseSelection,preview,@grafana/oss-big-tent,false,false,true sqlDatasourceDatabaseSelection,preview,@grafana/oss-big-tent,false,false,true

1 Name Stage Owner requiresDevMode RequiresRestart FrontendOnly
33 faroDatasourceSelector preview @grafana/app-o11y false false true
34 enableDatagridEditing preview @grafana/dataviz-squad false false true
35 extraThemes experimental @grafana/grafana-frontend-platform false false true
lokiPredefinedOperations experimental @grafana/observability-logs false false true
36 pluginsFrontendSandbox privatePreview @grafana/plugins-platform-backend false false false
37 pluginsDetailsRightPanel GA @grafana/plugins-platform-backend false false true
38 sqlDatasourceDatabaseSelection preview @grafana/oss-big-tent false false true

View File

@ -143,10 +143,6 @@ const (
// Enables extra themes // Enables extra themes
FlagExtraThemes = "extraThemes" FlagExtraThemes = "extraThemes"
// FlagLokiPredefinedOperations
// Adds predefined query operations to Loki query editor
FlagLokiPredefinedOperations = "lokiPredefinedOperations"
// FlagPluginsFrontendSandbox // FlagPluginsFrontendSandbox
// Enables the plugins frontend sandbox // Enables the plugins frontend sandbox
FlagPluginsFrontendSandbox = "pluginsFrontendSandbox" FlagPluginsFrontendSandbox = "pluginsFrontendSandbox"

View File

@ -1846,7 +1846,8 @@
"metadata": { "metadata": {
"name": "lokiPredefinedOperations", "name": "lokiPredefinedOperations",
"resourceVersion": "1750434297879", "resourceVersion": "1750434297879",
"creationTimestamp": "2023-06-02T10:52:36Z" "creationTimestamp": "2023-06-02T10:52:36Z",
"deletionTimestamp": "2025-06-27T08:08:44Z"
}, },
"spec": { "spec": {
"description": "Adds predefined query operations to Loki query editor", "description": "Adds predefined query operations to Loki query editor",

View File

@ -12,7 +12,7 @@ import {
QueryHeaderSwitch, QueryHeaderSwitch,
QueryEditorMode, QueryEditorMode,
} from '@grafana/plugin-ui'; } from '@grafana/plugin-ui';
import { config, reportInteraction } from '@grafana/runtime'; import { reportInteraction } from '@grafana/runtime';
import { Button, ConfirmModal, Space, Stack } from '@grafana/ui'; import { Button, ConfirmModal, Space, Stack } from '@grafana/ui';
import { LabelBrowserModal } from '../querybuilder/components/LabelBrowserModal'; import { LabelBrowserModal } from '../querybuilder/components/LabelBrowserModal';
@ -43,13 +43,9 @@ export const LokiQueryEditor = memo<LokiQueryEditorProps>((props) => {
const [queryStats, setQueryStats] = useState<QueryStats | null>(null); const [queryStats, setQueryStats] = useState<QueryStats | null>(null);
const [explain, setExplain] = useState(window.localStorage.getItem(lokiQueryEditorExplainKey) === 'true'); const [explain, setExplain] = useState(window.localStorage.getItem(lokiQueryEditorExplainKey) === 'true');
const predefinedOperations = datasource.predefinedOperations;
const previousTimeRange = usePrevious(timeRange); const previousTimeRange = usePrevious(timeRange);
const query = getQueryWithDefaults(props.query); const query = getQueryWithDefaults(props.query);
if (config.featureToggles.lokiPredefinedOperations && !query.expr && predefinedOperations) {
query.expr = `{} ${predefinedOperations}`;
}
const previousQueryExpr = usePrevious(query.expr); const previousQueryExpr = usePrevious(query.expr);
const previousQueryType = usePrevious(query.queryType); const previousQueryType = usePrevious(query.queryType);

View File

@ -1,5 +1,3 @@
import { useCallback } from 'react';
import { DataSourcePluginOptionsEditorProps, DataSourceSettings } from '@grafana/data'; import { DataSourcePluginOptionsEditorProps, DataSourceSettings } from '@grafana/data';
import { import {
ConfigSection, ConfigSection,
@ -9,7 +7,7 @@ import {
convertLegacyAuthProps, convertLegacyAuthProps,
AdvancedHttpSettings, AdvancedHttpSettings,
} from '@grafana/plugin-ui'; } from '@grafana/plugin-ui';
import { config, reportInteraction } from '@grafana/runtime'; import { config } from '@grafana/runtime';
import { Divider, SecureSocksProxySettings, Stack } from '@grafana/ui'; import { Divider, SecureSocksProxySettings, Stack } from '@grafana/ui';
import { LokiOptions } from '../types'; import { LokiOptions } from '../types';
@ -33,20 +31,10 @@ const makeJsonUpdater =
}; };
const setMaxLines = makeJsonUpdater('maxLines'); const setMaxLines = makeJsonUpdater('maxLines');
const setPredefinedOperations = makeJsonUpdater('predefinedOperations');
const setDerivedFields = makeJsonUpdater('derivedFields'); const setDerivedFields = makeJsonUpdater('derivedFields');
export const ConfigEditor = (props: Props) => { export const ConfigEditor = (props: Props) => {
const { options, onOptionsChange } = props; const { options, onOptionsChange } = props;
const updatePredefinedOperations = useCallback(
(value: string) => {
reportInteraction('grafana_loki_predefined_operations_changed', { value });
onOptionsChange(setPredefinedOperations(options, value));
},
[options, onOptionsChange]
);
return ( return (
<> <>
<DataSourceDescription <DataSourceDescription
@ -79,8 +67,6 @@ export const ConfigEditor = (props: Props) => {
<QuerySettings <QuerySettings
maxLines={options.jsonData.maxLines || ''} maxLines={options.jsonData.maxLines || ''}
onMaxLinedChange={(value) => onOptionsChange(setMaxLines(options, value))} onMaxLinedChange={(value) => onOptionsChange(setMaxLines(options, value))}
predefinedOperations={options.jsonData.predefinedOperations || ''}
onPredefinedOperationsChange={updatePredefinedOperations}
/> />
<DerivedFields <DerivedFields
fields={options.jsonData.derivedFields} fields={options.jsonData.derivedFields}

View File

@ -1,18 +1,15 @@
import * as React from 'react'; import * as React from 'react';
import { ConfigDescriptionLink, ConfigSubSection } from '@grafana/plugin-ui'; import { ConfigDescriptionLink, ConfigSubSection } from '@grafana/plugin-ui';
import { config } from '@grafana/runtime'; import { InlineField, Input } from '@grafana/ui';
import { Badge, InlineField, InlineFieldRow, Input } from '@grafana/ui';
type Props = { type Props = {
maxLines: string; maxLines: string;
onMaxLinedChange: (value: string) => void; onMaxLinedChange: (value: string) => void;
predefinedOperations: string;
onPredefinedOperationsChange: (value: string) => void;
}; };
export const QuerySettings = (props: Props) => { export const QuerySettings = (props: Props) => {
const { maxLines, onMaxLinedChange, predefinedOperations, onPredefinedOperationsChange } = props; const { maxLines, onMaxLinedChange } = props;
return ( return (
<ConfigSubSection <ConfigSubSection
title="Queries" title="Queries"
@ -46,43 +43,6 @@ export const QuerySettings = (props: Props) => {
spellCheck={false} spellCheck={false}
/> />
</InlineField> </InlineField>
{config.featureToggles.lokiPredefinedOperations && (
<InlineFieldRow>
<InlineField
label="Predefined operations"
htmlFor="loki_config_predefinedOperations"
labelWidth={22}
tooltip={
<>
{
'Predefined operations are used as an initial state for your queries. They are useful, if you want to unpack, parse or format all log lines. Currently we support only log operations starting with |. For example: | unpack | line_format "{{.message}}".'
}
</>
}
>
<Input
type="string"
id="loki_config_predefinedOperations"
value={predefinedOperations}
onChange={(event: React.FormEvent<HTMLInputElement>) =>
onPredefinedOperationsChange(event.currentTarget.value)
}
width={40}
placeholder="| unpack | line_format"
spellCheck={false}
/>
</InlineField>
<InlineField>
<Badge
text="Experimental"
color="orange"
icon="exclamation-triangle"
tooltip="Predefined operations is an experimental feature that may change in the future."
/>
</InlineField>
</InlineFieldRow>
)}
</ConfigSubSection> </ConfigSubSection>
); );
}; };

View File

@ -147,7 +147,6 @@ export class LokiDatasource
private logContextProvider: LogContextProvider; private logContextProvider: LogContextProvider;
languageProvider: LanguageProvider; languageProvider: LanguageProvider;
maxLines: number; maxLines: number;
predefinedOperations: string;
constructor( constructor(
private instanceSettings: DataSourceInstanceSettings<LokiOptions>, private instanceSettings: DataSourceInstanceSettings<LokiOptions>,
@ -158,7 +157,6 @@ export class LokiDatasource
this.languageProvider = new LanguageProvider(this); this.languageProvider = new LanguageProvider(this);
const settingsData = instanceSettings.jsonData || {}; const settingsData = instanceSettings.jsonData || {};
this.maxLines = parseInt(settingsData.maxLines ?? '0', 10) || DEFAULT_MAX_LINES; this.maxLines = parseInt(settingsData.maxLines ?? '0', 10) || DEFAULT_MAX_LINES;
this.predefinedOperations = settingsData.predefinedOperations ?? '';
this.annotations = { this.annotations = {
QueryEditor: LokiAnnotationsQueryEditor, QueryEditor: LokiAnnotationsQueryEditor,
}; };
@ -342,11 +340,7 @@ export class LokiDatasource
} }
const startTime = new Date(); const startTime = new Date();
return this.runQuery(fixedRequest).pipe( return this.runQuery(fixedRequest).pipe(tap((response) => trackQuery(response, fixedRequest, startTime)));
tap((response) =>
trackQuery(response, fixedRequest, startTime, { predefinedOperations: this.predefinedOperations })
)
);
} }
/** /**

View File

@ -306,8 +306,7 @@ describe('runSplitQuery()', () => {
}, },
], ],
request, request,
new Date(), new Date()
{ predefinedOperations: '' }
); );
}); });
}); });
@ -336,8 +335,7 @@ describe('runSplitQuery()', () => {
}, },
], ],
request, request,
new Date(), new Date()
{ predefinedOperations: '' }
); );
}); });
}); });

View File

@ -359,9 +359,7 @@ export function runSplitQuery(
return runSplitGroupedQueries(datasource, requests, options).pipe( return runSplitGroupedQueries(datasource, requests, options).pipe(
tap((response) => { tap((response) => {
if (response.state === LoadingState.Done) { if (response.state === LoadingState.Done) {
trackGroupedQueries(response, requests, request, startTime, { trackGroupedQueries(response, requests, request, startTime);
predefinedOperations: datasource.predefinedOperations,
});
} }
}) })
); );

View File

@ -85,7 +85,6 @@ describe('Tracks queries', () => {
time_range_from: '2023-02-08T05:00:00.000Z', time_range_from: '2023-02-08T05:00:00.000Z',
time_range_to: '2023-02-10T06:00:00.000Z', time_range_to: '2023-02-10T06:00:00.000Z',
time_taken: 0, time_taken: 0,
predefined_operations_applied: 'n/a',
}); });
}); });
@ -100,31 +99,6 @@ describe('Tracks queries', () => {
}); });
}); });
test('Tracks predefined operations', () => {
trackQuery({ data: [] }, originalRequest, new Date(), { predefinedOperations: 'count_over_time' });
expect(reportInteraction).toHaveBeenCalledWith('grafana_explore_loki_query_executed', {
bytes_processed: 0,
editor_mode: 'builder',
grafana_version: '1.0',
has_data: false,
has_error: false,
is_split: false,
legend: undefined,
line_limit: undefined,
obfuscated_query: 'count_over_time({Identifier=String}[1m])',
query_type: 'metric',
query_vector_type: undefined,
resolution: 1,
simultaneously_executed_query_count: 2,
simultaneously_hidden_query_count: 1,
time_range_from: '2023-02-08T05:00:00.000Z',
time_range_to: '2023-02-10T06:00:00.000Z',
time_taken: 0,
predefined_operations_applied: true,
});
});
test('Tracks grouped queries', () => { test('Tracks grouped queries', () => {
trackGroupedQueries({ data: [] }, requests, originalRequest, new Date()); trackGroupedQueries({ data: [] }, requests, originalRequest, new Date());
@ -150,7 +124,6 @@ test('Tracks grouped queries', () => {
time_range_from: '2023-02-08T05:00:00.000Z', time_range_from: '2023-02-08T05:00:00.000Z',
time_range_to: '2023-02-10T06:00:00.000Z', time_range_to: '2023-02-10T06:00:00.000Z',
time_taken: 0, time_taken: 0,
predefined_operations_applied: 'n/a',
}); });
expect(reportInteraction).toHaveBeenCalledWith('grafana_explore_loki_query_executed', { expect(reportInteraction).toHaveBeenCalledWith('grafana_explore_loki_query_executed', {
@ -175,7 +148,6 @@ test('Tracks grouped queries', () => {
time_range_from: '2023-02-08T05:00:00.000Z', time_range_from: '2023-02-08T05:00:00.000Z',
time_range_to: '2023-02-10T06:00:00.000Z', time_range_to: '2023-02-10T06:00:00.000Z',
time_taken: 0, time_taken: 0,
predefined_operations_applied: 'n/a',
}); });
}); });

View File

@ -53,10 +53,6 @@ type LokiOnDashboardLoadedTrackingEvent = {
queries_with_changed_legend_count: number; queries_with_changed_legend_count: number;
}; };
export type LokiTrackingSettings = {
predefinedOperations?: string;
};
export const onDashboardLoadedHandler = ({ export const onDashboardLoadedHandler = ({
payload: { dashboardId, orgId, grafanaVersion, queries }, payload: { dashboardId, orgId, grafanaVersion, queries },
}: DashboardLoadedEvent<LokiQuery>) => { }: DashboardLoadedEvent<LokiQuery>) => {
@ -158,7 +154,6 @@ export function trackQuery(
response: DataQueryResponse, response: DataQueryResponse,
request: DataQueryRequest<LokiQuery>, request: DataQueryRequest<LokiQuery>,
startTime: Date, startTime: Date,
trackingSettings: LokiTrackingSettings = {},
extraPayload: Record<string, unknown> = {} extraPayload: Record<string, unknown> = {}
): void { ): void {
// We only want to track usage for these specific apps // We only want to track usage for these specific apps
@ -193,9 +188,6 @@ export function trackQuery(
time_taken: Date.now() - startTime.getTime(), time_taken: Date.now() - startTime.getTime(),
bytes_processed: totalBytes, bytes_processed: totalBytes,
is_split: false, is_split: false,
predefined_operations_applied: trackingSettings.predefinedOperations
? query.expr.includes(trackingSettings.predefinedOperations)
: 'n/a',
...extraPayload, ...extraPayload,
}); });
} }
@ -205,8 +197,7 @@ export function trackGroupedQueries(
response: DataQueryResponse, response: DataQueryResponse,
groupedRequests: LokiGroupedRequest[], groupedRequests: LokiGroupedRequest[],
originalRequest: DataQueryRequest<LokiQuery>, originalRequest: DataQueryRequest<LokiQuery>,
startTime: Date, startTime: Date
trackingSettings: LokiTrackingSettings = {}
): void { ): void {
const splittingPayload = { const splittingPayload = {
split_query_group_count: groupedRequests.length, split_query_group_count: groupedRequests.length,
@ -219,7 +210,7 @@ export function trackGroupedQueries(
for (const group of groupedRequests) { for (const group of groupedRequests) {
const split_query_partition_size = group.partition.length; const split_query_partition_size = group.partition.length;
trackQuery(response, group.request, startTime, trackingSettings, { trackQuery(response, group.request, startTime, {
...splittingPayload, ...splittingPayload,
split_query_partition_size, split_query_partition_size,
}); });

View File

@ -43,7 +43,6 @@ export interface LokiOptions extends DataSourceJsonData {
derivedFields?: DerivedFieldConfig[]; derivedFields?: DerivedFieldConfig[];
alertmanager?: string; alertmanager?: string;
keepCookies?: string[]; keepCookies?: string[];
predefinedOperations?: string;
} }
export interface LokiStreamResult { export interface LokiStreamResult {