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
14 changed files with 12 additions and 133 deletions
@@ -166,10 +166,6 @@ export interface FeatureToggles {
*/
extraThemes?: boolean;
/**
* Adds predefined query operations to Loki query editor
*/
lokiPredefinedOperations?: boolean;
/**
* Enables the plugins frontend sandbox
*/
pluginsFrontendSandbox?: boolean;
-7
View File
@@ -262,13 +262,6 @@ var (
Stage: FeatureStageExperimental,
Owner: grafanaFrontendPlatformSquad,
},
{
Name: "lokiPredefinedOperations",
Description: "Adds predefined query operations to Loki query editor",
FrontendOnly: true,
Stage: FeatureStageExperimental,
Owner: grafanaObservabilityLogsSquad,
},
{
Name: "pluginsFrontendSandbox",
Description: "Enables the plugins frontend sandbox",
-1
View File
@@ -33,7 +33,6 @@ refactorVariablesTimeRange,preview,@grafana/dashboards-squad,false,false,false
faroDatasourceSelector,preview,@grafana/app-o11y,false,false,true
enableDatagridEditing,preview,@grafana/dataviz-squad,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
pluginsDetailsRightPanel,GA,@grafana/plugins-platform-backend,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
-4
View File
@@ -143,10 +143,6 @@ const (
// Enables extra themes
FlagExtraThemes = "extraThemes"
// FlagLokiPredefinedOperations
// Adds predefined query operations to Loki query editor
FlagLokiPredefinedOperations = "lokiPredefinedOperations"
// FlagPluginsFrontendSandbox
// Enables the plugins frontend sandbox
FlagPluginsFrontendSandbox = "pluginsFrontendSandbox"
+2 -1
View File
@@ -1846,7 +1846,8 @@
"metadata": {
"name": "lokiPredefinedOperations",
"resourceVersion": "1750434297879",
"creationTimestamp": "2023-06-02T10:52:36Z"
"creationTimestamp": "2023-06-02T10:52:36Z",
"deletionTimestamp": "2025-06-27T08:08:44Z"
},
"spec": {
"description": "Adds predefined query operations to Loki query editor",
@@ -12,7 +12,7 @@ import {
QueryHeaderSwitch,
QueryEditorMode,
} from '@grafana/plugin-ui';
import { config, reportInteraction } from '@grafana/runtime';
import { reportInteraction } from '@grafana/runtime';
import { Button, ConfirmModal, Space, Stack } from '@grafana/ui';
import { LabelBrowserModal } from '../querybuilder/components/LabelBrowserModal';
@@ -43,13 +43,9 @@ export const LokiQueryEditor = memo<LokiQueryEditorProps>((props) => {
const [queryStats, setQueryStats] = useState<QueryStats | null>(null);
const [explain, setExplain] = useState(window.localStorage.getItem(lokiQueryEditorExplainKey) === 'true');
const predefinedOperations = datasource.predefinedOperations;
const previousTimeRange = usePrevious(timeRange);
const query = getQueryWithDefaults(props.query);
if (config.featureToggles.lokiPredefinedOperations && !query.expr && predefinedOperations) {
query.expr = `{} ${predefinedOperations}`;
}
const previousQueryExpr = usePrevious(query.expr);
const previousQueryType = usePrevious(query.queryType);
@@ -1,5 +1,3 @@
import { useCallback } from 'react';
import { DataSourcePluginOptionsEditorProps, DataSourceSettings } from '@grafana/data';
import {
ConfigSection,
@@ -9,7 +7,7 @@ import {
convertLegacyAuthProps,
AdvancedHttpSettings,
} from '@grafana/plugin-ui';
import { config, reportInteraction } from '@grafana/runtime';
import { config } from '@grafana/runtime';
import { Divider, SecureSocksProxySettings, Stack } from '@grafana/ui';
import { LokiOptions } from '../types';
@@ -33,20 +31,10 @@ const makeJsonUpdater =
};
const setMaxLines = makeJsonUpdater('maxLines');
const setPredefinedOperations = makeJsonUpdater('predefinedOperations');
const setDerivedFields = makeJsonUpdater('derivedFields');
export const ConfigEditor = (props: Props) => {
const { options, onOptionsChange } = props;
const updatePredefinedOperations = useCallback(
(value: string) => {
reportInteraction('grafana_loki_predefined_operations_changed', { value });
onOptionsChange(setPredefinedOperations(options, value));
},
[options, onOptionsChange]
);
return (
<>
<DataSourceDescription
@@ -79,8 +67,6 @@ export const ConfigEditor = (props: Props) => {
<QuerySettings
maxLines={options.jsonData.maxLines || ''}
onMaxLinedChange={(value) => onOptionsChange(setMaxLines(options, value))}
predefinedOperations={options.jsonData.predefinedOperations || ''}
onPredefinedOperationsChange={updatePredefinedOperations}
/>
<DerivedFields
fields={options.jsonData.derivedFields}
@@ -1,18 +1,15 @@
import * as React from 'react';
import { ConfigDescriptionLink, ConfigSubSection } from '@grafana/plugin-ui';
import { config } from '@grafana/runtime';
import { Badge, InlineField, InlineFieldRow, Input } from '@grafana/ui';
import { InlineField, Input } from '@grafana/ui';
type Props = {
maxLines: string;
onMaxLinedChange: (value: string) => void;
predefinedOperations: string;
onPredefinedOperationsChange: (value: string) => void;
};
export const QuerySettings = (props: Props) => {
const { maxLines, onMaxLinedChange, predefinedOperations, onPredefinedOperationsChange } = props;
const { maxLines, onMaxLinedChange } = props;
return (
<ConfigSubSection
title="Queries"
@@ -46,43 +43,6 @@ export const QuerySettings = (props: Props) => {
spellCheck={false}
/>
</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>
);
};
@@ -147,7 +147,6 @@ export class LokiDatasource
private logContextProvider: LogContextProvider;
languageProvider: LanguageProvider;
maxLines: number;
predefinedOperations: string;
constructor(
private instanceSettings: DataSourceInstanceSettings<LokiOptions>,
@@ -158,7 +157,6 @@ export class LokiDatasource
this.languageProvider = new LanguageProvider(this);
const settingsData = instanceSettings.jsonData || {};
this.maxLines = parseInt(settingsData.maxLines ?? '0', 10) || DEFAULT_MAX_LINES;
this.predefinedOperations = settingsData.predefinedOperations ?? '';
this.annotations = {
QueryEditor: LokiAnnotationsQueryEditor,
};
@@ -342,11 +340,7 @@ export class LokiDatasource
}
const startTime = new Date();
return this.runQuery(fixedRequest).pipe(
tap((response) =>
trackQuery(response, fixedRequest, startTime, { predefinedOperations: this.predefinedOperations })
)
);
return this.runQuery(fixedRequest).pipe(tap((response) => trackQuery(response, fixedRequest, startTime)));
}
/**
@@ -306,8 +306,7 @@ describe('runSplitQuery()', () => {
},
],
request,
new Date(),
{ predefinedOperations: '' }
new Date()
);
});
});
@@ -336,8 +335,7 @@ describe('runSplitQuery()', () => {
},
],
request,
new Date(),
{ predefinedOperations: '' }
new Date()
);
});
});
@@ -359,9 +359,7 @@ export function runSplitQuery(
return runSplitGroupedQueries(datasource, requests, options).pipe(
tap((response) => {
if (response.state === LoadingState.Done) {
trackGroupedQueries(response, requests, request, startTime, {
predefinedOperations: datasource.predefinedOperations,
});
trackGroupedQueries(response, requests, request, startTime);
}
})
);
@@ -85,7 +85,6 @@ describe('Tracks queries', () => {
time_range_from: '2023-02-08T05:00:00.000Z',
time_range_to: '2023-02-10T06:00:00.000Z',
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', () => {
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_to: '2023-02-10T06:00:00.000Z',
time_taken: 0,
predefined_operations_applied: 'n/a',
});
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_to: '2023-02-10T06:00:00.000Z',
time_taken: 0,
predefined_operations_applied: 'n/a',
});
});
+2 -11
View File
@@ -53,10 +53,6 @@ type LokiOnDashboardLoadedTrackingEvent = {
queries_with_changed_legend_count: number;
};
export type LokiTrackingSettings = {
predefinedOperations?: string;
};
export const onDashboardLoadedHandler = ({
payload: { dashboardId, orgId, grafanaVersion, queries },
}: DashboardLoadedEvent<LokiQuery>) => {
@@ -158,7 +154,6 @@ export function trackQuery(
response: DataQueryResponse,
request: DataQueryRequest<LokiQuery>,
startTime: Date,
trackingSettings: LokiTrackingSettings = {},
extraPayload: Record<string, unknown> = {}
): void {
// We only want to track usage for these specific apps
@@ -193,9 +188,6 @@ export function trackQuery(
time_taken: Date.now() - startTime.getTime(),
bytes_processed: totalBytes,
is_split: false,
predefined_operations_applied: trackingSettings.predefinedOperations
? query.expr.includes(trackingSettings.predefinedOperations)
: 'n/a',
...extraPayload,
});
}
@@ -205,8 +197,7 @@ export function trackGroupedQueries(
response: DataQueryResponse,
groupedRequests: LokiGroupedRequest[],
originalRequest: DataQueryRequest<LokiQuery>,
startTime: Date,
trackingSettings: LokiTrackingSettings = {}
startTime: Date
): void {
const splittingPayload = {
split_query_group_count: groupedRequests.length,
@@ -219,7 +210,7 @@ export function trackGroupedQueries(
for (const group of groupedRequests) {
const split_query_partition_size = group.partition.length;
trackQuery(response, group.request, startTime, trackingSettings, {
trackQuery(response, group.request, startTime, {
...splittingPayload,
split_query_partition_size,
});
@@ -43,7 +43,6 @@ export interface LokiOptions extends DataSourceJsonData {
derivedFields?: DerivedFieldConfig[];
alertmanager?: string;
keepCookies?: string[];
predefinedOperations?: string;
}
export interface LokiStreamResult {