Loki: remove query formatting (#88636)

* Loki: remove query formatting

* Loki formatting: remove feature flag

* chore: remove test

* Formatting
This commit is contained in:
Matias Chomicki 2024-06-05 11:46:28 +02:00 committed by GitHub
parent 9bec35563a
commit ec9aecd82b
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
9 changed files with 1768 additions and 1887 deletions

View File

@ -137,7 +137,6 @@ Experimental features might be changed or removed without prior notice.
| `lokiPredefinedOperations` | Adds predefined query operations to Loki query editor | | `lokiPredefinedOperations` | Adds predefined query operations to Loki query editor |
| `pluginsFrontendSandbox` | Enables the plugins frontend sandbox | | `pluginsFrontendSandbox` | Enables the plugins frontend sandbox |
| `frontendSandboxMonitorOnly` | Enables monitor only in the plugin frontend sandbox (if enabled) | | `frontendSandboxMonitorOnly` | Enables monitor only in the plugin frontend sandbox (if enabled) |
| `lokiFormatQuery` | Enables the ability to format Loki queries |
| `vizAndWidgetSplit` | Split panels between visualizations and widgets | | `vizAndWidgetSplit` | Split panels between visualizations and widgets |
| `prometheusIncrementalQueryInstrumentation` | Adds RudderStack events to incremental queries | | `prometheusIncrementalQueryInstrumentation` | Adds RudderStack events to incremental queries |
| `awsDatasourcesTempCredentials` | Support temporary security credentials in AWS plugins for Grafana Cloud customers | | `awsDatasourcesTempCredentials` | Support temporary security credentials in AWS plugins for Grafana Cloud customers |

View File

@ -81,7 +81,6 @@ export interface FeatureToggles {
pluginsFrontendSandbox?: boolean; pluginsFrontendSandbox?: boolean;
frontendSandboxMonitorOnly?: boolean; frontendSandboxMonitorOnly?: boolean;
sqlDatasourceDatabaseSelection?: boolean; sqlDatasourceDatabaseSelection?: boolean;
lokiFormatQuery?: boolean;
recordedQueriesMulti?: boolean; recordedQueriesMulti?: boolean;
vizAndWidgetSplit?: boolean; vizAndWidgetSplit?: boolean;
prometheusIncrementalQueryInstrumentation?: boolean; prometheusIncrementalQueryInstrumentation?: boolean;

View File

@ -471,13 +471,6 @@ var (
Owner: grafanaDatavizSquad, Owner: grafanaDatavizSquad,
HideFromAdminPage: true, HideFromAdminPage: true,
}, },
{
Name: "lokiFormatQuery",
Description: "Enables the ability to format Loki queries",
FrontendOnly: true,
Stage: FeatureStageExperimental,
Owner: grafanaObservabilityLogsSquad,
},
{ {
Name: "recordedQueriesMulti", Name: "recordedQueriesMulti",
Description: "Enables writing multiple items from a single query within Recorded Queries", Description: "Enables writing multiple items from a single query within Recorded Queries",

View File

@ -62,7 +62,6 @@ lokiPredefinedOperations,experimental,@grafana/observability-logs,false,false,tr
pluginsFrontendSandbox,experimental,@grafana/plugins-platform-backend,false,false,true pluginsFrontendSandbox,experimental,@grafana/plugins-platform-backend,false,false,true
frontendSandboxMonitorOnly,experimental,@grafana/plugins-platform-backend,false,false,true frontendSandboxMonitorOnly,experimental,@grafana/plugins-platform-backend,false,false,true
sqlDatasourceDatabaseSelection,preview,@grafana/dataviz-squad,false,false,true sqlDatasourceDatabaseSelection,preview,@grafana/dataviz-squad,false,false,true
lokiFormatQuery,experimental,@grafana/observability-logs,false,false,true
recordedQueriesMulti,GA,@grafana/observability-metrics,false,false,false recordedQueriesMulti,GA,@grafana/observability-metrics,false,false,false
vizAndWidgetSplit,experimental,@grafana/dashboards-squad,false,false,true vizAndWidgetSplit,experimental,@grafana/dashboards-squad,false,false,true
prometheusIncrementalQueryInstrumentation,experimental,@grafana/observability-metrics,false,false,true prometheusIncrementalQueryInstrumentation,experimental,@grafana/observability-metrics,false,false,true

1 Name Stage Owner requiresDevMode RequiresRestart FrontendOnly
62 pluginsFrontendSandbox experimental @grafana/plugins-platform-backend false false true
63 frontendSandboxMonitorOnly experimental @grafana/plugins-platform-backend false false true
64 sqlDatasourceDatabaseSelection preview @grafana/dataviz-squad false false true
lokiFormatQuery experimental @grafana/observability-logs false false true
65 recordedQueriesMulti GA @grafana/observability-metrics false false false
66 vizAndWidgetSplit experimental @grafana/dashboards-squad false false true
67 prometheusIncrementalQueryInstrumentation experimental @grafana/observability-metrics false false true

View File

@ -259,10 +259,6 @@ const (
// Enables previous SQL data source dataset dropdown behavior // Enables previous SQL data source dataset dropdown behavior
FlagSqlDatasourceDatabaseSelection = "sqlDatasourceDatabaseSelection" FlagSqlDatasourceDatabaseSelection = "sqlDatasourceDatabaseSelection"
// FlagLokiFormatQuery
// Enables the ability to format Loki queries
FlagLokiFormatQuery = "lokiFormatQuery"
// FlagRecordedQueriesMulti // FlagRecordedQueriesMulti
// Enables writing multiple items from a single query within Recorded Queries // Enables writing multiple items from a single query within Recorded Queries
FlagRecordedQueriesMulti = "recordedQueriesMulti" FlagRecordedQueriesMulti = "recordedQueriesMulti"

File diff suppressed because it is too large Load Diff

View File

@ -1,6 +1,5 @@
import { String } from '@grafana/lezer-logql'; import { String } from '@grafana/lezer-logql';
import { createLokiDatasource } from './__mocks__/datasource';
import { import {
getHighlighterExpressionsFromQuery, getHighlighterExpressionsFromQuery,
getLokiQueryType, getLokiQueryType,
@ -17,7 +16,6 @@ import {
getLogQueryFromMetricsQuery, getLogQueryFromMetricsQuery,
getNormalizedLokiQuery, getNormalizedLokiQuery,
getNodePositionsFromQuery, getNodePositionsFromQuery,
formatLogqlQuery,
getLogQueryFromMetricsQueryAtPosition, getLogQueryFromMetricsQueryAtPosition,
} from './queryUtils'; } from './queryUtils';
import { LokiQuery, LokiQueryType } from './types'; import { LokiQuery, LokiQueryType } from './types';
@ -491,27 +489,3 @@ describe('getNodePositionsFromQuery', () => {
expect(nodePositions.length).toBe(0); expect(nodePositions.length).toBe(0);
}); });
}); });
describe('formatLogqlQuery', () => {
const ds = createLokiDatasource();
it('formats a logs query', () => {
expect(formatLogqlQuery('{job="grafana"}', ds)).toBe('{job="grafana"}');
});
it('formats a metrics query', () => {
expect(formatLogqlQuery('count_over_time({job="grafana"}[1m])', ds)).toBe(
'count_over_time(\n {job="grafana"}\n [1m]\n)'
);
});
it('formats a metrics query with variables', () => {
// mock the interpolateString return value so it passes the isValid check
ds.interpolateString = jest.fn(() => 'rate({job="grafana"}[1s])');
expect(formatLogqlQuery('rate({job="grafana"}[$__range])', ds)).toBe('rate(\n {job="grafana"}\n [$__range]\n)');
expect(formatLogqlQuery('rate({job="grafana"}[$__interval])', ds)).toBe(
'rate(\n {job="grafana"}\n [$__interval]\n)'
);
});
});

View File

@ -18,19 +18,15 @@ import {
Matcher, Matcher,
Identifier, Identifier,
Range, Range,
formatLokiQuery,
Logfmt, Logfmt,
Json, Json,
OrFilter, OrFilter,
FilterOp, FilterOp,
} from '@grafana/lezer-logql'; } from '@grafana/lezer-logql';
import { reportInteraction } from '@grafana/runtime';
import { DataQuery } from '@grafana/schema'; import { DataQuery } from '@grafana/schema';
import { placeHolderScopedVars } from './components/monaco-query-field/monaco-completion-provider/validation';
import { LokiDatasource } from './datasource';
import { getStreamSelectorPositions, NodePosition } from './modifyQuery'; import { getStreamSelectorPositions, NodePosition } from './modifyQuery';
import { ErrorId, replaceVariables, returnVariables } from './querybuilder/parsingUtils'; import { ErrorId } from './querybuilder/parsingUtils';
import { LokiQuery, LokiQueryType } from './types'; import { LokiQuery, LokiQueryType } from './types';
/** /**
@ -320,39 +316,3 @@ export const getLokiQueryFromDataQuery = (query?: DataQuery): LokiQuery | undefi
return query; return query;
}; };
export function formatLogqlQuery(query: string, datasource: LokiDatasource) {
const isInvalid = isQueryWithError(datasource.interpolateString(query, placeHolderScopedVars));
reportInteraction('grafana_loki_format_query_clicked', {
is_invalid: isInvalid,
query_type: isLogsQuery(query) ? 'logs' : 'metric',
});
if (isInvalid) {
return query;
}
let transformedQuery = replaceVariables(query);
const transformationMatches = [];
const tree = parser.parse(transformedQuery);
// Variables are considered errors inside of the parser, so we need to remove them before formatting
// We replace all variables with [0s] and keep track of the replaced variables
// After formatting we replace [0s] with the original variable
if (tree.topNode.firstChild?.firstChild?.type.id === MetricExpr) {
const pattern = /\[__V_[0-2]__\w+__V__\]/g;
transformationMatches.push(...transformedQuery.matchAll(pattern));
transformedQuery = transformedQuery.replace(pattern, '[0s]');
}
let formatted = formatLokiQuery(transformedQuery);
if (tree.topNode.firstChild?.firstChild?.type.id === MetricExpr) {
transformationMatches.forEach((match) => {
formatted = formatted.replace('[0s]', match[0]);
});
}
return returnVariables(formatted);
}

View File

@ -2,13 +2,11 @@ import { css } from '@emotion/css';
import React from 'react'; import React from 'react';
import { GrafanaTheme2 } from '@grafana/data'; import { GrafanaTheme2 } from '@grafana/data';
import { config } from '@grafana/runtime'; import { useStyles2 } from '@grafana/ui';
import { useStyles2, IconButton, Tooltip, Icon, Stack } from '@grafana/ui';
import { testIds } from '../../components/LokiQueryEditor'; import { testIds } from '../../components/LokiQueryEditor';
import { LokiQueryField } from '../../components/LokiQueryField'; import { LokiQueryField } from '../../components/LokiQueryField';
import { LokiQueryEditorProps } from '../../components/types'; import { LokiQueryEditorProps } from '../../components/types';
import { formatLogqlQuery } from '../../queryUtils';
import { LokiQueryBuilderExplained } from './LokiQueryBuilderExplained'; import { LokiQueryBuilderExplained } from './LokiQueryBuilderExplained';
@ -29,9 +27,6 @@ export function LokiQueryCodeEditor({
}: Props) { }: Props) {
const styles = useStyles2(getStyles); const styles = useStyles2(getStyles);
const lokiFormatQuery = config.featureToggles.lokiFormatQuery;
const onClickFormatQueryButton = async () => onChange({ ...query, expr: formatLogqlQuery(query.expr, datasource) });
return ( return (
<div className={styles.wrapper}> <div className={styles.wrapper}>
<LokiQueryField <LokiQueryField
@ -44,27 +39,6 @@ export function LokiQueryCodeEditor({
data={data} data={data}
app={app} app={app}
data-testid={testIds.editor} data-testid={testIds.editor}
ExtraFieldElement={
<>
{lokiFormatQuery && (
<div className={styles.buttonGroup}>
<div>
<Stack gap={1}>
<IconButton
onClick={onClickFormatQueryButton}
name="brackets-curly"
size="xs"
tooltip="Format query"
/>
<Tooltip content={`Use ctrl/cmd + z to undo`}>
<Icon className={styles.hint} name="keyboard" />
</Tooltip>
</Stack>
</div>
</div>
)}
</>
}
/> />
{showExplain && <LokiQueryBuilderExplained query={query.expr} />} {showExplain && <LokiQueryBuilderExplained query={query.expr} />}
</div> </div>