mirror of
https://github.com/grafana/grafana.git
synced 2025-08-06 18:15:25 +08:00
Chore: Remove unused parseSelector function (#108119)
remove unused parseSelector
This commit is contained in:
@ -9,84 +9,12 @@ import {
|
|||||||
fixSummariesMetadata,
|
fixSummariesMetadata,
|
||||||
getPrometheusTime,
|
getPrometheusTime,
|
||||||
getRangeSnapInterval,
|
getRangeSnapInterval,
|
||||||
parseSelector,
|
|
||||||
processLabels,
|
processLabels,
|
||||||
toPromLikeQuery,
|
toPromLikeQuery,
|
||||||
truncateResult,
|
truncateResult,
|
||||||
} from './language_utils';
|
} from './language_utils';
|
||||||
import { PrometheusCacheLevel } from './types';
|
import { PrometheusCacheLevel } from './types';
|
||||||
|
|
||||||
describe('parseSelector()', () => {
|
|
||||||
let parsed;
|
|
||||||
|
|
||||||
it('returns a clean selector from an empty selector', () => {
|
|
||||||
parsed = parseSelector('{}', 1);
|
|
||||||
expect(parsed.selector).toBe('{}');
|
|
||||||
expect(parsed.labelKeys).toEqual([]);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('returns a clean selector from an unclosed selector', () => {
|
|
||||||
const parsed = parseSelector('{foo');
|
|
||||||
expect(parsed.selector).toBe('{}');
|
|
||||||
});
|
|
||||||
|
|
||||||
it('returns the selector sorted by label key', () => {
|
|
||||||
parsed = parseSelector('{foo="bar"}');
|
|
||||||
expect(parsed.selector).toBe('{foo="bar"}');
|
|
||||||
expect(parsed.labelKeys).toEqual(['foo']);
|
|
||||||
|
|
||||||
parsed = parseSelector('{foo="bar",baz="xx"}');
|
|
||||||
expect(parsed.selector).toBe('{baz="xx",foo="bar"}');
|
|
||||||
});
|
|
||||||
|
|
||||||
it('returns a clean selector from an incomplete one', () => {
|
|
||||||
parsed = parseSelector('{foo}');
|
|
||||||
expect(parsed.selector).toBe('{}');
|
|
||||||
|
|
||||||
parsed = parseSelector('{foo="bar",baz}');
|
|
||||||
expect(parsed.selector).toBe('{foo="bar"}');
|
|
||||||
|
|
||||||
parsed = parseSelector('{foo="bar",baz="}');
|
|
||||||
expect(parsed.selector).toBe('{foo="bar"}');
|
|
||||||
|
|
||||||
// Cursor in value area counts as incomplete
|
|
||||||
parsed = parseSelector('{foo="bar",baz=""}', 16);
|
|
||||||
expect(parsed.selector).toBe('{foo="bar"}');
|
|
||||||
|
|
||||||
parsed = parseSelector('{foo="bar",baz="4"}', 17);
|
|
||||||
expect(parsed.selector).toBe('{foo="bar"}');
|
|
||||||
});
|
|
||||||
|
|
||||||
it('throws if not inside a selector', () => {
|
|
||||||
expect(() => parseSelector('foo{}', 0)).toThrow();
|
|
||||||
expect(() => parseSelector('foo{} + bar{}', 5)).toThrow();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('returns the selector nearest to the cursor offset', () => {
|
|
||||||
expect(() => parseSelector('{foo="bar"} + {foo="bar"}', 0)).toThrow();
|
|
||||||
|
|
||||||
parsed = parseSelector('{foo="bar"} + {foo="bar"}', 1);
|
|
||||||
expect(parsed.selector).toBe('{foo="bar"}');
|
|
||||||
|
|
||||||
parsed = parseSelector('{foo="bar"} + {baz="xx"}', 1);
|
|
||||||
expect(parsed.selector).toBe('{foo="bar"}');
|
|
||||||
|
|
||||||
parsed = parseSelector('{baz="xx"} + {foo="bar"}', 16);
|
|
||||||
expect(parsed.selector).toBe('{foo="bar"}');
|
|
||||||
});
|
|
||||||
|
|
||||||
it('returns a selector with metric if metric is given', () => {
|
|
||||||
parsed = parseSelector('bar{foo}', 4);
|
|
||||||
expect(parsed.selector).toBe('{__name__="bar"}');
|
|
||||||
|
|
||||||
parsed = parseSelector('baz{foo="bar"}', 13);
|
|
||||||
expect(parsed.selector).toBe('{__name__="baz",foo="bar"}');
|
|
||||||
|
|
||||||
parsed = parseSelector('bar:metric:1m{}', 14);
|
|
||||||
expect(parsed.selector).toBe('{__name__="bar:metric:1m"}');
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('fixSummariesMetadata', () => {
|
describe('fixSummariesMetadata', () => {
|
||||||
const synthetics = {
|
const synthetics = {
|
||||||
ALERTS: {
|
ALERTS: {
|
||||||
|
@ -63,9 +63,6 @@ export function processLabels(labels: Array<{ [key: string]: string }>, withName
|
|||||||
return { values: valueArray, keys: Object.keys(valueArray) };
|
return { values: valueArray, keys: Object.keys(valueArray) };
|
||||||
}
|
}
|
||||||
|
|
||||||
// const cleanSelectorRegexp = /\{(\w+="[^"\n]*?")(,\w+="[^"\n]*?")*\}/;
|
|
||||||
export const selectorRegexp = /\{[^}]*?(\}|$)/;
|
|
||||||
|
|
||||||
// This will capture 4 groups. Example label filter => {instance="10.4.11.4:9003"}
|
// This will capture 4 groups. Example label filter => {instance="10.4.11.4:9003"}
|
||||||
// 1. label: instance
|
// 1. label: instance
|
||||||
// 2. operator: =
|
// 2. operator: =
|
||||||
@ -75,70 +72,6 @@ export const selectorRegexp = /\{[^}]*?(\}|$)/;
|
|||||||
// comma and space is useful for addLabelsToExpression function
|
// comma and space is useful for addLabelsToExpression function
|
||||||
export const labelRegexp = /\b(\w+)(!?=~?)("[^"\n]*?")(,)?(\s*)?/g;
|
export const labelRegexp = /\b(\w+)(!?=~?)("[^"\n]*?")(,)?(\s*)?/g;
|
||||||
|
|
||||||
export function parseSelector(query: string, cursorOffset = 1): { labelKeys: string[]; selector: string } {
|
|
||||||
if (!query.match(selectorRegexp)) {
|
|
||||||
// Special matcher for metrics
|
|
||||||
if (query.match(/^[A-Za-z:][\w:]*$/)) {
|
|
||||||
return {
|
|
||||||
selector: `{__name__="${query}"}`,
|
|
||||||
labelKeys: ['__name__'],
|
|
||||||
};
|
|
||||||
}
|
|
||||||
throw new Error('Query must contain a selector: ' + query);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check if inside a selector
|
|
||||||
const prefix = query.slice(0, cursorOffset);
|
|
||||||
const prefixOpen = prefix.lastIndexOf('{');
|
|
||||||
const prefixClose = prefix.lastIndexOf('}');
|
|
||||||
if (prefixOpen === -1) {
|
|
||||||
throw new Error('Not inside selector, missing open brace: ' + prefix);
|
|
||||||
}
|
|
||||||
if (prefixClose > -1 && prefixClose > prefixOpen) {
|
|
||||||
throw new Error('Not inside selector, previous selector already closed: ' + prefix);
|
|
||||||
}
|
|
||||||
const suffix = query.slice(cursorOffset);
|
|
||||||
const suffixCloseIndex = suffix.indexOf('}');
|
|
||||||
const suffixClose = suffixCloseIndex + cursorOffset;
|
|
||||||
const suffixOpenIndex = suffix.indexOf('{');
|
|
||||||
const suffixOpen = suffixOpenIndex + cursorOffset;
|
|
||||||
if (suffixClose === -1) {
|
|
||||||
throw new Error('Not inside selector, missing closing brace in suffix: ' + suffix);
|
|
||||||
}
|
|
||||||
if (suffixOpenIndex > -1 && suffixOpen < suffixClose) {
|
|
||||||
throw new Error('Not inside selector, next selector opens before this one closed: ' + suffix);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Extract clean labels to form clean selector, incomplete labels are dropped
|
|
||||||
const selector = query.slice(prefixOpen, suffixClose);
|
|
||||||
const labels: { [key: string]: { value: string; operator: string } } = {};
|
|
||||||
selector.replace(labelRegexp, (label, key, operator, value) => {
|
|
||||||
const labelOffset = query.indexOf(label);
|
|
||||||
const valueStart = labelOffset + key.length + operator.length + 1;
|
|
||||||
const valueEnd = labelOffset + key.length + operator.length + value.length - 1;
|
|
||||||
// Skip label if cursor is in value
|
|
||||||
if (cursorOffset < valueStart || cursorOffset > valueEnd) {
|
|
||||||
labels[key] = { value, operator };
|
|
||||||
}
|
|
||||||
return '';
|
|
||||||
});
|
|
||||||
|
|
||||||
// Add metric if there is one before the selector
|
|
||||||
const metricPrefix = query.slice(0, prefixOpen);
|
|
||||||
const metricMatch = metricPrefix.match(/[A-Za-z:][\w:]*$/);
|
|
||||||
if (metricMatch) {
|
|
||||||
labels['__name__'] = { value: `"${metricMatch[0]}"`, operator: '=' };
|
|
||||||
}
|
|
||||||
|
|
||||||
// Build sorted selector
|
|
||||||
const labelKeys = Object.keys(labels).sort();
|
|
||||||
const cleanSelector = labelKeys.map((key) => `${key}${labels[key].operator}${labels[key].value}`).join(',');
|
|
||||||
|
|
||||||
const selectorString = ['{', cleanSelector, '}'].join('');
|
|
||||||
|
|
||||||
return { labelKeys, selector: selectorString };
|
|
||||||
}
|
|
||||||
|
|
||||||
export function expandRecordingRules(query: string, mapping: { [name: string]: RecordingRuleIdentifier }): string {
|
export function expandRecordingRules(query: string, mapping: { [name: string]: RecordingRuleIdentifier }): string {
|
||||||
const getRuleRegex = (ruleName: string) => new RegExp(`(\\s|\\(|^)(${ruleName})(\\s|$|\\(|\\[|\\{)`, 'ig');
|
const getRuleRegex = (ruleName: string) => new RegExp(`(\\s|\\(|^)(${ruleName})(\\s|$|\\(|\\[|\\{)`, 'ig');
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user