From a1bc1bd36855f1ad37dc5aba82984de890645c5a Mon Sep 17 00:00:00 2001 From: Galen Kistler <109082771+gtk-grafana@users.noreply.github.com> Date: Mon, 8 May 2023 11:33:30 -0500 Subject: [PATCH] Prometheus: bug in creating autocomplete queries with labels (#68003) Fix bug formatting multiple prometheus labels when doing metric query --- .../components/MetricSelect.test.tsx | 44 ++++++++++++++++++- .../querybuilder/components/MetricSelect.tsx | 35 +++++++-------- 2 files changed, 59 insertions(+), 20 deletions(-) diff --git a/public/app/plugins/datasource/prometheus/querybuilder/components/MetricSelect.test.tsx b/public/app/plugins/datasource/prometheus/querybuilder/components/MetricSelect.test.tsx index 63344ad82e5..ade5c9d2c84 100644 --- a/public/app/plugins/datasource/prometheus/querybuilder/components/MetricSelect.test.tsx +++ b/public/app/plugins/datasource/prometheus/querybuilder/components/MetricSelect.test.tsx @@ -7,7 +7,12 @@ import { DataSourceInstanceSettings, MetricFindValue } from '@grafana/data/src'; import { PrometheusDatasource } from '../../datasource'; import { PromOptions } from '../../types'; -import { MetricSelect, Props } from './MetricSelect'; +import { + formatPrometheusLabelFilters, + formatPrometheusLabelFiltersToString, + MetricSelect, + Props, +} from './MetricSelect'; const instanceSettings = { url: 'proxied', @@ -130,6 +135,43 @@ describe('MetricSelect', () => { await userEvent.type(input, 'new'); await waitFor(() => expect(document.querySelector('mark')).not.toBeInTheDocument()); }); + + it('label filters properly join', () => { + const query = formatPrometheusLabelFilters([ + { + value: 'value', + label: 'label', + op: '=', + }, + { + value: 'value2', + label: 'label2', + op: '=', + }, + ]); + query.forEach((label) => { + expect(label.includes(',', 0)); + }); + }); + it('label filter creation', () => { + const labels = [ + { + value: 'value', + label: 'label', + op: '=', + }, + { + value: 'value2', + label: 'label2', + op: '=', + }, + ]; + + const queryString = formatPrometheusLabelFiltersToString('query', labels); + queryString.split(',').forEach((queryChunk) => { + expect(queryChunk.length).toBeGreaterThan(1); // must be longer then ',' + }); + }); }); async function openMetricSelect() { diff --git a/public/app/plugins/datasource/prometheus/querybuilder/components/MetricSelect.tsx b/public/app/plugins/datasource/prometheus/querybuilder/components/MetricSelect.tsx index 02611841f5d..4469bc41d71 100644 --- a/public/app/plugins/datasource/prometheus/querybuilder/components/MetricSelect.tsx +++ b/public/app/plugins/datasource/prometheus/querybuilder/components/MetricSelect.tsx @@ -81,24 +81,6 @@ export function MetricSelect({ [styles.highlight] ); - const formatLabelFilters = (labelsFilters: QueryBuilderLabelFilter[]): string[] => { - return labelsFilters.map((label) => { - return `,${label.label}="${label.value}"`; - }); - }; - - /** - * Transform queryString and any currently set label filters into label_values() string - */ - const queryAndFilterToLabelValuesString = ( - queryString: string, - labelsFilters: QueryBuilderLabelFilter[] | undefined - ): string => { - return `label_values({__name__=~".*${queryString}"${ - labelsFilters ? formatLabelFilters(labelsFilters).join() : '' - }},__name__)`; - }; - /** * Reformat the query string and label filters to return all valid results for current query editor state */ @@ -108,7 +90,7 @@ export function MetricSelect({ ): string => { const queryString = regexifyLabelValuesQueryString(query); - return queryAndFilterToLabelValuesString(queryString, labelsFilters); + return formatPrometheusLabelFiltersToString(queryString, labelsFilters); }; /** @@ -284,3 +266,18 @@ const getStyles = (theme: GrafanaTheme2) => ({ background-color: ${theme.colors.emphasize(theme.colors.background.primary, 0.03)}; `, }); + +export const formatPrometheusLabelFiltersToString = ( + queryString: string, + labelsFilters: QueryBuilderLabelFilter[] | undefined +): string => { + const filterArray = labelsFilters ? formatPrometheusLabelFilters(labelsFilters) : []; + + return `label_values({__name__=~".*${queryString}"${filterArray ? filterArray.join('') : ''}},__name__)`; +}; + +export const formatPrometheusLabelFilters = (labelsFilters: QueryBuilderLabelFilter[]): string[] => { + return labelsFilters.map((label) => { + return `,${label.label}="${label.value}"`; + }); +};