grafana/public/app/plugins/datasource/loki/query_utils.ts

71 lines
2.0 KiB
TypeScript
Raw Normal View History

import { LokiExpression } from './types';
const selectorRegexp = /(?:^|\s){[^{]*}/g;
const caseInsensitive = '(?i)'; // Golang mode modifier for Loki, doesn't work in JavaScript
export function parseQuery(input: string): LokiExpression {
input = input || '';
const match = input.match(selectorRegexp);
let query = input;
let regexp = '';
if (match) {
regexp = input.replace(selectorRegexp, '').trim();
// Keep old-style regexp, otherwise take whole query
if (regexp && regexp.search(/\|=|\|~|!=|!~/) === -1) {
query = match[0].trim();
if (!regexp.startsWith(caseInsensitive)) {
regexp = `${caseInsensitive}${regexp}`;
}
} else {
regexp = '';
}
}
return { regexp, query };
}
export function formatQuery(selector: string, search: string): string {
return `${selector || ''} ${search || ''}`.trim();
}
/**
* Returns search terms from a LogQL query.
* E.g., `{} |= foo |=bar != baz` returns `['foo', 'bar']`.
*/
export function getHighlighterExpressionsFromQuery(input: string): string[] {
const parsed = parseQuery(input);
// Legacy syntax
if (parsed.regexp) {
return [parsed.regexp];
}
let expression = input;
const results = [];
// Consume filter expression from left to right
while (expression) {
const filterStart = expression.search(/\|=|\|~|!=|!~/);
// Nothing more to search
if (filterStart === -1) {
break;
}
// Drop terms for negative filters
const skip = expression.substr(filterStart).search(/!=|!~/) === 0;
expression = expression.substr(filterStart + 2);
if (skip) {
continue;
}
// Check if there is more chained
const filterEnd = expression.search(/\|=|\|~|!=|!~/);
let filterTerm;
if (filterEnd === -1) {
filterTerm = expression.trim();
} else {
filterTerm = expression.substr(0, filterEnd);
expression = expression.substr(filterEnd);
}
// Unwrap the filter term by removing quotes
results.push(filterTerm.replace(/^\s*"/g, '').replace(/"\s*$/g, ''));
}
return results;
}