2022-12-14 13:43:06 +01:00
|
|
|
import { chain } from 'lodash';
|
|
|
|
|
|
2022-10-06 16:35:30 +02:00
|
|
|
import { HistoryItem } from '@grafana/data';
|
|
|
|
|
import { escapeLabelValueInExactSelector } from 'app/plugins/datasource/prometheus/language_utils';
|
|
|
|
|
|
|
|
|
|
import LanguageProvider from '../../../LanguageProvider';
|
|
|
|
|
import { LokiQuery } from '../../../types';
|
|
|
|
|
|
|
|
|
|
import { Label } from './situation';
|
|
|
|
|
|
|
|
|
|
export class CompletionDataProvider {
|
2022-12-14 13:43:06 +01:00
|
|
|
private history: string[] = [];
|
|
|
|
|
constructor(private languageProvider: LanguageProvider, history: Array<HistoryItem<LokiQuery>> = []) {
|
|
|
|
|
this.setHistory(history);
|
|
|
|
|
}
|
2022-10-06 16:35:30 +02:00
|
|
|
|
|
|
|
|
private buildSelector(labels: Label[]): string {
|
|
|
|
|
const allLabelTexts = labels.map(
|
|
|
|
|
(label) => `${label.name}${label.op}"${escapeLabelValueInExactSelector(label.value)}"`
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
return `{${allLabelTexts.join(',')}}`;
|
|
|
|
|
}
|
|
|
|
|
|
2022-12-14 13:43:06 +01:00
|
|
|
setHistory(history: Array<HistoryItem<LokiQuery>> = []) {
|
|
|
|
|
this.history = chain(history)
|
|
|
|
|
.map((history: HistoryItem<LokiQuery>) => history.query.expr)
|
|
|
|
|
.filter()
|
|
|
|
|
.uniq()
|
|
|
|
|
.value();
|
|
|
|
|
}
|
|
|
|
|
|
2022-10-06 16:35:30 +02:00
|
|
|
getHistory() {
|
2022-12-14 13:43:06 +01:00
|
|
|
return this.history;
|
2022-10-06 16:35:30 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
async getLabelNames(otherLabels: Label[] = []) {
|
|
|
|
|
if (otherLabels.length === 0) {
|
|
|
|
|
// if there is no filtering, we have to use a special endpoint
|
|
|
|
|
return this.languageProvider.getLabelKeys();
|
|
|
|
|
}
|
|
|
|
|
const data = await this.getSeriesLabels(otherLabels);
|
|
|
|
|
const possibleLabelNames = Object.keys(data); // all names from datasource
|
|
|
|
|
const usedLabelNames = new Set(otherLabels.map((l) => l.name)); // names used in the query
|
|
|
|
|
return possibleLabelNames.filter((label) => !usedLabelNames.has(label));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
async getLabelValues(labelName: string, otherLabels: Label[]) {
|
|
|
|
|
if (otherLabels.length === 0) {
|
|
|
|
|
// if there is no filtering, we have to use a special endpoint
|
|
|
|
|
return await this.languageProvider.getLabelValues(labelName);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const data = await this.getSeriesLabels(otherLabels);
|
|
|
|
|
return data[labelName] ?? [];
|
|
|
|
|
}
|
|
|
|
|
|
2022-12-14 17:37:08 +01:00
|
|
|
async getParserAndLabelKeys(logQuery: string) {
|
|
|
|
|
return await this.languageProvider.getParserAndLabelKeys(logQuery);
|
2022-10-06 16:35:30 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
async getSeriesLabels(labels: Label[]) {
|
|
|
|
|
return await this.languageProvider.getSeriesLabels(this.buildSelector(labels)).then((data) => data ?? {});
|
|
|
|
|
}
|
|
|
|
|
}
|