The open and composable observability and data visualization platform. Visualize metrics, logs, and traces from multiple sources like Prometheus, Loki, Elasticsearch, InfluxDB, Postgres and many more.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 
grafana/public/app/plugins/datasource/prometheus/migrations/variableMigration.ts

137 lines
4.3 KiB

import { promQueryModeller } from '../querybuilder/PromQueryModeller';
import { buildVisualQueryFromString } from '../querybuilder/parsing';
import { PromVariableQuery, PromVariableQueryType as QueryType } from '../types';
export const PrometheusLabelNamesRegex = /^label_names\(\)\s*$/;
// Note that this regex is different from the one in metric_find_query.ts because this is used pre-interpolation
export const PrometheusLabelValuesRegex = /^label_values\((?:(.+),\s*)?([a-zA-Z_$][a-zA-Z0-9_]*)\)\s*$/;
export const PrometheusMetricNamesRegex = /^metrics\((.+)\)\s*$/;
export const PrometheusQueryResultRegex = /^query_result\((.+)\)\s*$/;
export const PrometheusLabelNamesRegexWithMatch = /^label_names\((.+)\)\s*$/;
export function migrateVariableQueryToEditor(rawQuery: string | PromVariableQuery): PromVariableQuery {
// If not string, we assume PromVariableQuery
if (typeof rawQuery !== 'string') {
return rawQuery;
}
const queryBase = {
refId: 'PrometheusDatasource-VariableQuery',
qryType: QueryType.LabelNames,
};
const labelNamesMatchQuery = rawQuery.match(PrometheusLabelNamesRegexWithMatch);
if (labelNamesMatchQuery) {
return {
...queryBase,
qryType: QueryType.LabelNames,
match: labelNamesMatchQuery[1],
};
}
const labelNames = rawQuery.match(PrometheusLabelNamesRegex);
if (labelNames) {
return {
...queryBase,
qryType: QueryType.LabelNames,
};
}
const labelValuesCheck = rawQuery.match(/^label_values\(/);
if (labelValuesCheck) {
const labelValues = rawQuery.match(PrometheusLabelValuesRegex);
const label = labelValues ? labelValues[2] : '';
const metric = labelValues ? labelValues[1] : '';
if (metric) {
const visQuery = buildVisualQueryFromString(metric);
return {
...queryBase,
qryType: QueryType.LabelValues,
label,
metric: visQuery.query.metric,
labelFilters: visQuery.query.labels,
};
} else {
return {
...queryBase,
qryType: QueryType.LabelValues,
label,
};
}
}
const metricNamesCheck = rawQuery.match(/^metrics\(/);
if (metricNamesCheck) {
const metricNames = rawQuery.match(PrometheusMetricNamesRegex);
const metric = metricNames ? metricNames[1] : '';
return {
...queryBase,
qryType: QueryType.MetricNames,
metric,
};
}
const queryResultCheck = rawQuery.match(/^query_result\(/);
if (queryResultCheck) {
const queryResult = rawQuery.match(PrometheusQueryResultRegex);
const varQuery = queryResult ? queryResult[1] : '';
return {
...queryBase,
qryType: QueryType.VarQueryResult,
varQuery,
};
}
// seriesQuery does not have a function and no regex above
if (!labelNames && !labelValuesCheck && !metricNamesCheck && !queryResultCheck) {
return {
...queryBase,
qryType: QueryType.SeriesQuery,
seriesQuery: rawQuery,
};
}
return queryBase;
}
// migrate it back to a string with the correct varialbes in place
export function migrateVariableEditorBackToVariableSupport(QueryVariable: PromVariableQuery): string {
switch (QueryVariable.qryType) {
case QueryType.LabelNames:
if (QueryVariable.match) {
return `label_names(${QueryVariable.match})`;
}
return 'label_names()';
case QueryType.LabelValues:
if (QueryVariable.metric || (QueryVariable.labelFilters && QueryVariable.labelFilters.length !== 0)) {
const visualQueryQuery = {
metric: QueryVariable.metric,
labels: QueryVariable.labelFilters ?? [],
operations: [],
};
const metric = promQueryModeller.renderQuery(visualQueryQuery);
return `label_values(${metric},${QueryVariable.label})`;
} else {
return `label_values(${QueryVariable.label})`;
}
case QueryType.MetricNames:
return `metrics(${QueryVariable.metric})`;
case QueryType.VarQueryResult:
const varQuery = removeLineBreaks(QueryVariable.varQuery);
return `query_result(${varQuery})`;
case QueryType.SeriesQuery:
return QueryVariable.seriesQuery ?? '';
case QueryType.ClassicQuery:
return QueryVariable.classicQuery ?? '';
}
return '';
}
// allow line breaks in query result textarea
function removeLineBreaks(input?: string) {
return input ? input.replace(/[\r\n]+/gm, '') : '';
}