Prometheus: bug in creating autocomplete queries with labels (#68003)

Fix bug formatting multiple prometheus labels when doing metric query
This commit is contained in:
Galen Kistler 2023-05-08 11:33:30 -05:00 committed by GitHub
parent 5416ec4768
commit a1bc1bd368
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 59 additions and 20 deletions

View File

@ -7,7 +7,12 @@ import { DataSourceInstanceSettings, MetricFindValue } from '@grafana/data/src';
import { PrometheusDatasource } from '../../datasource'; import { PrometheusDatasource } from '../../datasource';
import { PromOptions } from '../../types'; import { PromOptions } from '../../types';
import { MetricSelect, Props } from './MetricSelect'; import {
formatPrometheusLabelFilters,
formatPrometheusLabelFiltersToString,
MetricSelect,
Props,
} from './MetricSelect';
const instanceSettings = { const instanceSettings = {
url: 'proxied', url: 'proxied',
@ -130,6 +135,43 @@ describe('MetricSelect', () => {
await userEvent.type(input, 'new'); await userEvent.type(input, 'new');
await waitFor(() => expect(document.querySelector('mark')).not.toBeInTheDocument()); 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() { async function openMetricSelect() {

View File

@ -81,24 +81,6 @@ export function MetricSelect({
[styles.highlight] [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 * 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 => { ): string => {
const queryString = regexifyLabelValuesQueryString(query); 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)}; 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}"`;
});
};