mirror of
https://github.com/grafana/grafana.git
synced 2025-07-30 21:22:44 +08:00
Prometheus: UTF8 support in metrics browser (#98612)
* utf8 metrics for prometheus devenv * introduce utf8 support * completions and suggestions * don't wrap the utf8 label in quotes * linting * support utf8 labels and metrics on visual query builder * lint * update raw view for utf8 metric syntax * betterer * support utf8 metric names in explore metrics * utf8 support in grouop by * utf8 support in label break down * utf8 metric and label support in metric_find_query for label values * use the same regex to check label values * no need to escape * support series endpoint * support series endpoint * support series endpoint * support series endpoint * fix tests * fix extracting labels from labelValuesQuery * show explanation with right syntax * support utf8 metrics and labels
This commit is contained in:
@ -54,6 +54,49 @@ describe('buildSelector()', () => {
|
||||
];
|
||||
expect(buildSelector(labels)).toEqual('foo{bar="baz"}');
|
||||
});
|
||||
|
||||
describe('utf8 support', () => {
|
||||
it('metric selector with utf8 metric', () => {
|
||||
const labels: SelectableLabel[] = [
|
||||
{ name: '__name__', selected: true, values: [{ name: 'utf8.metric', selected: true }] },
|
||||
];
|
||||
expect(buildSelector(labels)).toEqual('{"utf8.metric"}');
|
||||
});
|
||||
|
||||
it('metric selector with utf8 labels', () => {
|
||||
const labels: SelectableLabel[] = [
|
||||
{ name: '__name__', selected: true, values: [{ name: 'foo', selected: true }] },
|
||||
{ name: 'utf8.label', selected: true, values: [{ name: 'baz', selected: true }] },
|
||||
];
|
||||
expect(buildSelector(labels)).toEqual('foo{"utf8.label"="baz"}');
|
||||
});
|
||||
|
||||
it('metric selector with utf8 labels and metrics', () => {
|
||||
const labels: SelectableLabel[] = [
|
||||
{ name: '__name__', selected: true, values: [{ name: 'utf8.metric', selected: true }] },
|
||||
{ name: 'utf8.label', selected: true, values: [{ name: 'baz', selected: true }] },
|
||||
];
|
||||
expect(buildSelector(labels)).toEqual('{"utf8.metric","utf8.label"="baz"}');
|
||||
});
|
||||
|
||||
it('metric selector with utf8 metric and with utf8/non-utf8 labels', () => {
|
||||
const labels: SelectableLabel[] = [
|
||||
{ name: '__name__', selected: true, values: [{ name: 'utf8.metric', selected: true }] },
|
||||
{ name: 'utf8.label', selected: true, values: [{ name: 'uuu', selected: true }] },
|
||||
{ name: 'bar', selected: true, values: [{ name: 'baz', selected: true }] },
|
||||
];
|
||||
expect(buildSelector(labels)).toEqual('{"utf8.metric","utf8.label"="uuu",bar="baz"}');
|
||||
});
|
||||
|
||||
it('metric selector with non-utf8 metric with utf8/non-utf8 labels', () => {
|
||||
const labels: SelectableLabel[] = [
|
||||
{ name: '__name__', selected: true, values: [{ name: 'foo', selected: true }] },
|
||||
{ name: 'utf8.label', selected: true, values: [{ name: 'uuu', selected: true }] },
|
||||
{ name: 'bar', selected: true, values: [{ name: 'baz', selected: true }] },
|
||||
];
|
||||
expect(buildSelector(labels)).toEqual('foo{"utf8.label"="uuu",bar="baz"}');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('facetLabels()', () => {
|
||||
|
@ -19,6 +19,7 @@ import {
|
||||
|
||||
import PromQlLanguageProvider from '../language_provider';
|
||||
import { escapeLabelValueInExactSelector, escapeLabelValueInRegexSelector } from '../language_utils';
|
||||
import { isValidLegacyName, utf8Support } from '../utf8_support';
|
||||
|
||||
// Hard limit on labels to render
|
||||
const EMPTY_SELECTOR = '{}';
|
||||
@ -68,22 +69,38 @@ export interface SelectableLabel {
|
||||
|
||||
export function buildSelector(labels: SelectableLabel[]): string {
|
||||
let singleMetric = '';
|
||||
const selectedLabels = [];
|
||||
const selectedLabels: string[] = [];
|
||||
for (const label of labels) {
|
||||
if ((label.name === METRIC_LABEL || label.selected) && label.values && label.values.length > 0) {
|
||||
const selectedValues = label.values.filter((value) => value.selected).map((value) => value.name);
|
||||
if (selectedValues.length > 1) {
|
||||
selectedLabels.push(`${label.name}=~"${selectedValues.map(escapeLabelValueInRegexSelector).join('|')}"`);
|
||||
selectedLabels.push(
|
||||
`${utf8Support(label.name)}=~"${selectedValues.map(escapeLabelValueInRegexSelector).join('|')}"`
|
||||
);
|
||||
} else if (selectedValues.length === 1) {
|
||||
if (label.name === METRIC_LABEL) {
|
||||
singleMetric = selectedValues[0];
|
||||
} else {
|
||||
selectedLabels.push(`${label.name}="${escapeLabelValueInExactSelector(selectedValues[0])}"`);
|
||||
selectedLabels.push(`${utf8Support(label.name)}="${escapeLabelValueInExactSelector(selectedValues[0])}"`);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return [singleMetric, '{', selectedLabels.join(','), '}'].join('');
|
||||
|
||||
const selectorParts: string[] = [];
|
||||
const isLegacyName = singleMetric === '' || isValidLegacyName(singleMetric);
|
||||
|
||||
if (isLegacyName) {
|
||||
selectorParts.push(singleMetric, '{');
|
||||
} else {
|
||||
selectorParts.push('{', `"${singleMetric}"`);
|
||||
if (selectedLabels.length > 0) {
|
||||
selectorParts.push(',');
|
||||
}
|
||||
}
|
||||
|
||||
selectorParts.push(selectedLabels.join(','), '}');
|
||||
return selectorParts.join('');
|
||||
}
|
||||
|
||||
export function facetLabels(
|
||||
|
Reference in New Issue
Block a user