mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
prometheus: monaco: allow listing label names + values without a metric (#41233)
* prometheus: monaco: allow listing label names + values without a metric * removed comment
This commit is contained in:
parent
72ae3235fa
commit
91da1bbb79
@ -138,7 +138,11 @@ const MonacoQueryField = (props: Props) => {
|
|||||||
return Promise.resolve(result);
|
return Promise.resolve(result);
|
||||||
};
|
};
|
||||||
|
|
||||||
const dataProvider = { getSeries, getHistory, getAllMetricNames };
|
const getAllLabelNames = () => Promise.resolve(lpRef.current.getLabelKeys());
|
||||||
|
|
||||||
|
const getLabelValues = (labelName: string) => lpRef.current.getLabelValues(labelName);
|
||||||
|
|
||||||
|
const dataProvider = { getSeries, getHistory, getAllMetricNames, getAllLabelNames, getLabelValues };
|
||||||
const completionProvider = getCompletionProvider(monaco, dataProvider);
|
const completionProvider = getCompletionProvider(monaco, dataProvider);
|
||||||
|
|
||||||
// completion-providers in monaco are not registered directly to editor-instances,
|
// completion-providers in monaco are not registered directly to editor-instances,
|
||||||
|
@ -23,6 +23,8 @@ type Metric = {
|
|||||||
export type DataProvider = {
|
export type DataProvider = {
|
||||||
getHistory: () => Promise<string[]>;
|
getHistory: () => Promise<string[]>;
|
||||||
getAllMetricNames: () => Promise<Metric[]>;
|
getAllMetricNames: () => Promise<Metric[]>;
|
||||||
|
getAllLabelNames: () => Promise<string[]>;
|
||||||
|
getLabelValues: (labelName: string) => Promise<string[]>;
|
||||||
getSeries: (selector: string) => Promise<Record<string, string[]>>;
|
getSeries: (selector: string) => Promise<Record<string, string[]>>;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -93,6 +95,23 @@ function makeSelector(metricName: string | undefined, labels: Label[]): string {
|
|||||||
return `{${allLabelTexts.join(',')}}`;
|
return `{${allLabelTexts.join(',')}}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function getLabelNames(
|
||||||
|
metric: string | undefined,
|
||||||
|
otherLabels: Label[],
|
||||||
|
dataProvider: DataProvider
|
||||||
|
): Promise<string[]> {
|
||||||
|
if (metric === undefined && otherLabels.length === 0) {
|
||||||
|
// if there is no filtering, we have to use a special endpoint
|
||||||
|
return dataProvider.getAllLabelNames();
|
||||||
|
} else {
|
||||||
|
const selector = makeSelector(metric, otherLabels);
|
||||||
|
const data = await dataProvider.getSeries(selector);
|
||||||
|
const possibleLabelNames = Object.keys(data); // all names from prometheus
|
||||||
|
const usedLabelNames = new Set(otherLabels.map((l) => l.name)); // names used in the query
|
||||||
|
return possibleLabelNames.filter((l) => !usedLabelNames.has(l));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
async function getLabelNamesForCompletions(
|
async function getLabelNamesForCompletions(
|
||||||
metric: string | undefined,
|
metric: string | undefined,
|
||||||
suffix: string,
|
suffix: string,
|
||||||
@ -100,11 +119,7 @@ async function getLabelNamesForCompletions(
|
|||||||
otherLabels: Label[],
|
otherLabels: Label[],
|
||||||
dataProvider: DataProvider
|
dataProvider: DataProvider
|
||||||
): Promise<Completion[]> {
|
): Promise<Completion[]> {
|
||||||
const selector = makeSelector(metric, otherLabels);
|
const labelNames = await getLabelNames(metric, otherLabels, dataProvider);
|
||||||
const data = await dataProvider.getSeries(selector);
|
|
||||||
const possibleLabelNames = Object.keys(data); // all names from prometheus
|
|
||||||
const usedLabelNames = new Set(otherLabels.map((l) => l.name)); // names used in the query
|
|
||||||
const labelNames = possibleLabelNames.filter((l) => !usedLabelNames.has(l));
|
|
||||||
return labelNames.map((text) => ({
|
return labelNames.map((text) => ({
|
||||||
type: 'LABEL_NAME',
|
type: 'LABEL_NAME',
|
||||||
label: text,
|
label: text,
|
||||||
@ -128,15 +143,29 @@ async function getLabelNamesForByCompletions(
|
|||||||
return getLabelNamesForCompletions(metric, '', false, otherLabels, dataProvider);
|
return getLabelNamesForCompletions(metric, '', false, otherLabels, dataProvider);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function getLabelValues(
|
||||||
|
metric: string | undefined,
|
||||||
|
labelName: string,
|
||||||
|
otherLabels: Label[],
|
||||||
|
dataProvider: DataProvider
|
||||||
|
): Promise<string[]> {
|
||||||
|
if (metric === undefined && otherLabels.length === 0) {
|
||||||
|
// if there is no filtering, we have to use a special endpoint
|
||||||
|
return dataProvider.getLabelValues(labelName);
|
||||||
|
} else {
|
||||||
|
const selector = makeSelector(metric, otherLabels);
|
||||||
|
const data = await dataProvider.getSeries(selector);
|
||||||
|
return data[labelName] ?? [];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
async function getLabelValuesForMetricCompletions(
|
async function getLabelValuesForMetricCompletions(
|
||||||
metric: string | undefined,
|
metric: string | undefined,
|
||||||
labelName: string,
|
labelName: string,
|
||||||
otherLabels: Label[],
|
otherLabels: Label[],
|
||||||
dataProvider: DataProvider
|
dataProvider: DataProvider
|
||||||
): Promise<Completion[]> {
|
): Promise<Completion[]> {
|
||||||
const selector = makeSelector(metric, otherLabels);
|
const values = await getLabelValues(metric, labelName, otherLabels, dataProvider);
|
||||||
const data = await dataProvider.getSeries(selector);
|
|
||||||
const values = data[labelName] ?? [];
|
|
||||||
return values.map((text) => ({
|
return values.map((text) => ({
|
||||||
type: 'LABEL_VALUE',
|
type: 'LABEL_VALUE',
|
||||||
label: text,
|
label: text,
|
||||||
|
Loading…
Reference in New Issue
Block a user