Files

96 lines
2.8 KiB
TypeScript

import { default as GraphiteQueryModel } from '../../graphite/graphite_query';
import { map } from 'lodash';
import { LokiQuery } from '../types';
import { GraphiteDatasource } from '../../graphite/datasource';
import { getTemplateSrv } from '../../../../features/templating/template_srv';
import { GraphiteMetricLokiMatcher, GraphiteQuery, GraphiteToLokiQueryImportConfiguration } from '../../graphite/types';
const GRAPHITE_TO_LOKI_OPERATOR = {
'=': '=',
'!=': '!=',
'=~': '=~',
'!=~': '!~',
};
/**
* Converts Graphite glob-like pattern to a regular expression
*/
function convertGlobToRegEx(text: string): string {
if (text.includes('*') || text.includes('{')) {
return '^' + text.replace(/\*/g, '.*').replace(/\{/g, '(').replace(/}/g, ')').replace(/,/g, '|');
} else {
return text;
}
}
export default function fromGraphiteQueries(
graphiteQueries: GraphiteQuery[],
graphiteDataSource: GraphiteDatasource
): LokiQuery[] {
return graphiteQueries.map((query) => {
const model: GraphiteQueryModel = new GraphiteQueryModel(
graphiteDataSource,
{
...query,
target: query.target || '',
textEditor: false,
},
getTemplateSrv()
);
model.parseTarget();
return {
refId: query.refId,
expr: fromGraphite(model, graphiteDataSource.getImportQueryConfiguration().loki),
};
});
}
function fromGraphite(graphiteQuery: GraphiteQueryModel, config: GraphiteToLokiQueryImportConfiguration): string {
let matchingFound = false;
let labels: any = {};
if (graphiteQuery.seriesByTagUsed) {
matchingFound = true;
graphiteQuery.tags.forEach((tag) => {
labels[tag.key] = {
value: tag.value,
operator: GRAPHITE_TO_LOKI_OPERATOR[tag.operator],
};
});
} else {
const targetNodes = graphiteQuery.segments.map((segment) => segment.value);
let mappings = config.mappings.filter((mapping) => mapping.matchers.length <= targetNodes.length);
for (let mapping of mappings) {
const matchers = mapping.matchers.concat();
matchingFound = matchers.every((matcher: GraphiteMetricLokiMatcher, index: number) => {
if (matcher.labelName) {
let value = (targetNodes[index] as string)!;
if (value === '*') {
return true;
}
const converted = convertGlobToRegEx(value);
labels[matcher.labelName] = {
value: converted,
operator: converted !== value ? '=~' : '=',
};
return true;
}
return targetNodes[index] === matcher.value || matcher.value === '*';
});
}
}
let pairs = map(labels, (value, key) => `${key}${value.operator}"${value.value}"`);
if (matchingFound && pairs.length) {
return `{${pairs.join(', ')}}`;
} else {
return '';
}
}