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 |
| `pluginsFrontendSandbox` | Enables the plugins frontend sandbox |
| `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 |
| `prometheusIncrementalQueryInstrumentation` | Adds RudderStack events to incremental queries |
| `awsDatasourcesTempCredentials` | Support temporary security credentials in AWS plugins for Grafana Cloud customers |

View File

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

View File

@ -471,13 +471,6 @@ var (
Owner: grafanaDatavizSquad,
HideFromAdminPage: true,
},
{
Name: "lokiFormatQuery",
Description: "Enables the ability to format Loki queries",
FrontendOnly: true,
Stage: FeatureStageExperimental,
Owner: grafanaObservabilityLogsSquad,
},
{
Name: "recordedQueriesMulti",
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
frontendSandboxMonitorOnly,experimental,@grafana/plugins-platform-backend,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
vizAndWidgetSplit,experimental,@grafana/dashboards-squad,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
FlagSqlDatasourceDatabaseSelection = "sqlDatasourceDatabaseSelection"
// FlagLokiFormatQuery
// Enables the ability to format Loki queries
FlagLokiFormatQuery = "lokiFormatQuery"
// FlagRecordedQueriesMulti
// Enables writing multiple items from a single query within Recorded Queries
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 { createLokiDatasource } from './__mocks__/datasource';
import {
getHighlighterExpressionsFromQuery,
getLokiQueryType,
@ -17,7 +16,6 @@ import {
getLogQueryFromMetricsQuery,
getNormalizedLokiQuery,
getNodePositionsFromQuery,
formatLogqlQuery,
getLogQueryFromMetricsQueryAtPosition,
} from './queryUtils';
import { LokiQuery, LokiQueryType } from './types';
@ -491,27 +489,3 @@ describe('getNodePositionsFromQuery', () => {
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,
Identifier,
Range,
formatLokiQuery,
Logfmt,
Json,
OrFilter,
FilterOp,
} from '@grafana/lezer-logql';
import { reportInteraction } from '@grafana/runtime';
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 { ErrorId, replaceVariables, returnVariables } from './querybuilder/parsingUtils';
import { ErrorId } from './querybuilder/parsingUtils';
import { LokiQuery, LokiQueryType } from './types';
/**
@ -320,39 +316,3 @@ export const getLokiQueryFromDataQuery = (query?: DataQuery): LokiQuery | undefi
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 { GrafanaTheme2 } from '@grafana/data';
import { config } from '@grafana/runtime';
import { useStyles2, IconButton, Tooltip, Icon, Stack } from '@grafana/ui';
import { useStyles2 } from '@grafana/ui';
import { testIds } from '../../components/LokiQueryEditor';
import { LokiQueryField } from '../../components/LokiQueryField';
import { LokiQueryEditorProps } from '../../components/types';
import { formatLogqlQuery } from '../../queryUtils';
import { LokiQueryBuilderExplained } from './LokiQueryBuilderExplained';
@ -29,9 +27,6 @@ export function LokiQueryCodeEditor({
}: Props) {
const styles = useStyles2(getStyles);
const lokiFormatQuery = config.featureToggles.lokiFormatQuery;
const onClickFormatQueryButton = async () => onChange({ ...query, expr: formatLogqlQuery(query.expr, datasource) });
return (
<div className={styles.wrapper}>
<LokiQueryField
@ -44,27 +39,6 @@ export function LokiQueryCodeEditor({
data={data}
app={app}
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} />}
</div>