mirror of https://github.com/grafana/grafana.git
				
				
				
			Loki: Remove experimental predefined operations (#107289)
* Loki: Remove experimental predefined operations * Fix lint
This commit is contained in:
		
							parent
							
								
									7f2aed42a0
								
							
						
					
					
						commit
						cc542f2b91
					
				|  | @ -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; | ||||
|  |  | |||
|  | @ -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", | ||||
|  |  | |||
|  | @ -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 | ||||
|  |  | |||
| 
 | 
|  | @ -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" | ||||
|  |  | |||
|  | @ -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', | ||||
|   }); | ||||
| }); | ||||
| 
 | ||||
|  |  | |||
|  | @ -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 { | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue