diff --git a/docs/sources/setup-grafana/configure-grafana/feature-toggles/index.md b/docs/sources/setup-grafana/configure-grafana/feature-toggles/index.md index 9ad0bfaee3b..f439d728ea6 100644 --- a/docs/sources/setup-grafana/configure-grafana/feature-toggles/index.md +++ b/docs/sources/setup-grafana/configure-grafana/feature-toggles/index.md @@ -110,6 +110,7 @@ Alpha features might be changed or removed without prior notice. | `authenticationConfigUI` | Enables authentication configuration UI | | `pluginsAPIManifestKey` | Use grafana.com API to retrieve the public manifest key | | `extraThemes` | Enables extra themes | +| `lokiPredefinedOperations` | Adds predefined query operations to Loki query editor | ## Development feature toggles diff --git a/packages/grafana-data/src/types/featureToggles.gen.ts b/packages/grafana-data/src/types/featureToggles.gen.ts index 7437cb2d7e3..8780d28c1b9 100644 --- a/packages/grafana-data/src/types/featureToggles.gen.ts +++ b/packages/grafana-data/src/types/featureToggles.gen.ts @@ -97,4 +97,5 @@ export interface FeatureToggles { enableDatagridEditing?: boolean; dataSourcePageHeader?: boolean; extraThemes?: boolean; + lokiPredefinedOperations?: boolean; } diff --git a/pkg/services/featuremgmt/registry.go b/pkg/services/featuremgmt/registry.go index 6a281976423..bf0d55d69e3 100644 --- a/pkg/services/featuremgmt/registry.go +++ b/pkg/services/featuremgmt/registry.go @@ -535,5 +535,12 @@ var ( State: FeatureStateAlpha, Owner: grafanaUserEssentialsSquad, }, + { + Name: "lokiPredefinedOperations", + Description: "Adds predefined query operations to Loki query editor", + FrontendOnly: true, + State: FeatureStateAlpha, + Owner: grafanaObservabilityLogsSquad, + }, } ) diff --git a/pkg/services/featuremgmt/toggles_gen.csv b/pkg/services/featuremgmt/toggles_gen.csv index 14ff26b7517..e0a84dbf47c 100644 --- a/pkg/services/featuremgmt/toggles_gen.csv +++ b/pkg/services/featuremgmt/toggles_gen.csv @@ -78,3 +78,4 @@ faroDatasourceSelector,beta,@grafana/app-o11y,false,false,false,true enableDatagridEditing,beta,@grafana/grafana-bi-squad,false,false,false,true dataSourcePageHeader,beta,@grafana/enterprise-datasources,false,false,false,true extraThemes,alpha,@grafana/user-essentials,false,false,false,true +lokiPredefinedOperations,alpha,@grafana/observability-logs,false,false,false,true diff --git a/pkg/services/featuremgmt/toggles_gen.go b/pkg/services/featuremgmt/toggles_gen.go index 2658624ba55..7cc3435dc17 100644 --- a/pkg/services/featuremgmt/toggles_gen.go +++ b/pkg/services/featuremgmt/toggles_gen.go @@ -322,4 +322,8 @@ const ( // FlagExtraThemes // Enables extra themes FlagExtraThemes = "extraThemes" + + // FlagLokiPredefinedOperations + // Adds predefined query operations to Loki query editor + FlagLokiPredefinedOperations = "lokiPredefinedOperations" ) diff --git a/public/app/plugins/datasource/loki/components/LokiQueryEditor.tsx b/public/app/plugins/datasource/loki/components/LokiQueryEditor.tsx index bf459cf6ab4..ad57e77ad55 100644 --- a/public/app/plugins/datasource/loki/components/LokiQueryEditor.tsx +++ b/public/app/plugins/datasource/loki/components/LokiQueryEditor.tsx @@ -5,7 +5,7 @@ import { usePrevious } from 'react-use'; import { CoreApp, LoadingState } from '@grafana/data'; import { selectors } from '@grafana/e2e-selectors'; import { EditorHeader, EditorRows, FlexItem, Space, Stack } from '@grafana/experimental'; -import { reportInteraction } from '@grafana/runtime'; +import { config, reportInteraction } from '@grafana/runtime'; import { Button, ConfirmModal } from '@grafana/ui'; import { QueryEditorModeToggle } from 'app/plugins/datasource/prometheus/querybuilder/shared/QueryEditorModeToggle'; import { QueryHeaderSwitch } from 'app/plugins/datasource/prometheus/querybuilder/shared/QueryHeaderSwitch'; @@ -38,9 +38,13 @@ export const LokiQueryEditor = React.memo((props) => { const { flag: explain, setFlag: setExplain } = useFlag(lokiQueryEditorExplainKey); const timerange = datasource.getTimeRange(); + const predefinedOperations = datasource.predefinedOperations; const previousTimerange = usePrevious(timerange); const query = getQueryWithDefaults(props.query); + if (config.featureToggles.lokiPredefinedOperations && !query.expr && predefinedOperations) { + query.expr = `{} ${predefinedOperations}`; + } const previousQuery = usePrevious(query.expr); // This should be filled in from the defaults by now. diff --git a/public/app/plugins/datasource/loki/configuration/ConfigEditor.tsx b/public/app/plugins/datasource/loki/configuration/ConfigEditor.tsx index 405b5814a6e..c64c437b0d0 100644 --- a/public/app/plugins/datasource/loki/configuration/ConfigEditor.tsx +++ b/public/app/plugins/datasource/loki/configuration/ConfigEditor.tsx @@ -7,7 +7,7 @@ import { AlertingSettings, DataSourceHttpSettings } from '@grafana/ui'; import { LokiOptions } from '../types'; import { DerivedFields } from './DerivedFields'; -import { MaxLinesField } from './MaxLinesField'; +import { QuerySettings } from './QuerySettings'; export type Props = DataSourcePluginOptionsEditorProps; @@ -24,6 +24,7 @@ const makeJsonUpdater = }; const setMaxLines = makeJsonUpdater('maxLines'); +const setPredefinedOperations = makeJsonUpdater('predefinedOperations'); const setDerivedFields = makeJsonUpdater('derivedFields'); export const ConfigEditor = (props: Props) => { @@ -41,9 +42,11 @@ export const ConfigEditor = (props: Props) => { options={options} onOptionsChange={onOptionsChange} /> - onOptionsChange(setMaxLines(options, value))} + onOptionsChange(setMaxLines(options, value))} + predefinedOperations={options.jsonData.predefinedOperations || ''} + onPredefinedOperationsChange={(value) => onOptionsChange(setPredefinedOperations(options, value))} /> void; -}; - -export const MaxLinesField = (props: Props) => { - const { value, onChange } = props; - return ( - <> -

Queries

-
-
-
- onChange(event.currentTarget.value)} - spellCheck={false} - placeholder="1000" - /> - } - tooltip={ - <> - Loki queries must contain a limit of the maximum number of lines returned (default: 1000). Increase - this limit to have a bigger result set for ad-hoc analysis. Decrease this limit if your browser - becomes sluggish when displaying the log results. - - } - /> -
-
-
- - ); -}; diff --git a/public/app/plugins/datasource/loki/configuration/QuerySettings.tsx b/public/app/plugins/datasource/loki/configuration/QuerySettings.tsx new file mode 100644 index 00000000000..81db4661dba --- /dev/null +++ b/public/app/plugins/datasource/loki/configuration/QuerySettings.tsx @@ -0,0 +1,83 @@ +import React from 'react'; + +import { config } from '@grafana/runtime'; +import { Badge, LegacyForms } from '@grafana/ui'; + +const { FormField } = LegacyForms; + +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; + return ( + <> +

Queries

+
+
+
+ onMaxLinedChange(event.currentTarget.value)} + spellCheck={false} + placeholder="1000" + /> + } + tooltip={ + <> + Loki queries must contain a limit of the maximum number of lines returned (default: 1000). Increase + this limit to have a bigger result set for ad-hoc analysis. Decrease this limit if your browser + becomes sluggish when displaying the log results. + + } + /> +
+
+ {config.featureToggles.lokiPredefinedOperations && ( +
+
+ onPredefinedOperationsChange(event.currentTarget.value)} + spellCheck={false} + placeholder="| unpack | line_format" + /> + } + 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}}".' + } +
+ } + /> + +
+
+ )} +
+ + ); +}; diff --git a/public/app/plugins/datasource/loki/datasource.ts b/public/app/plugins/datasource/loki/datasource.ts index 8c941aceeb4..0aa609e7462 100644 --- a/public/app/plugins/datasource/loki/datasource.ts +++ b/public/app/plugins/datasource/loki/datasource.ts @@ -134,6 +134,7 @@ export class LokiDatasource languageProvider: LanguageProvider; logContextProvider: LogContextProvider; maxLines: number; + predefinedOperations: string; constructor( private instanceSettings: DataSourceInstanceSettings, @@ -145,6 +146,7 @@ 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, }; diff --git a/public/app/plugins/datasource/loki/types.ts b/public/app/plugins/datasource/loki/types.ts index 2d647684585..3ee8e96fc19 100644 --- a/public/app/plugins/datasource/loki/types.ts +++ b/public/app/plugins/datasource/loki/types.ts @@ -48,6 +48,7 @@ export interface LokiOptions extends DataSourceJsonData { derivedFields?: DerivedFieldConfig[]; alertmanager?: string; keepCookies?: string[]; + predefinedOperations?: string; } export interface LokiStats {