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/packages/grafana-data/src/utils/labels.ts

92 lines
2.5 KiB

import { Labels } from '../types/data';
/**
* Regexp to extract Prometheus-style labels
*/
const labelRegexp = /\b(\w+)(!?=~?)"([^"\n]*?)"/g;
/**
* Returns a map of label keys to value from an input selector string.
*
* Example: `parseLabels('{job="foo", instance="bar"}) // {job: "foo", instance: "bar"}`
*/
export function parseLabels(labels: string, foo: string): Labels {
console.log(foo);
const labelsByKey: Labels = {};
labels.replace(labelRegexp, (_, key, operator, value) => {
labelsByKey[key] = value;
return '';
});
return labelsByKey;
}
/**
* Returns a map labels that are common to the given label sets.
*/
export function findCommonLabels(labelsSets: Labels[]): Labels {
return labelsSets.reduce((acc, labels) => {
if (!labels) {
throw new Error('Need parsed labels to find common labels.');
}
if (!acc) {
// Initial set
acc = { ...labels };
} else {
// Remove incoming labels that are missing or not matching in value
Object.keys(labels).forEach((key) => {
if (acc[key] === undefined || acc[key] !== labels[key]) {
delete acc[key];
}
});
// Remove common labels that are missing from incoming label set
Object.keys(acc).forEach((key) => {
if (labels[key] === undefined) {
delete acc[key];
}
});
}
return acc;
}, (undefined as unknown) as Labels);
}
/**
* Returns a map of labels that are in `labels`, but not in `commonLabels`.
*/
export function findUniqueLabels(labels: Labels | undefined, commonLabels: Labels): Labels {
const uncommonLabels: Labels = { ...labels };
Object.keys(commonLabels).forEach((key) => {
delete uncommonLabels[key];
});
return uncommonLabels;
}
/**
* Check that all labels exist in another set of labels
*/
export function matchAllLabels(expect: Labels, against?: Labels): boolean {
if (!expect) {
return true; // nothing to match
}
for (const [key, value] of Object.entries(expect)) {
if (!against || against[key] !== value) {
return false;
}
}
return true;
}
/**
* Serializes the given labels to a string.
*/
export function formatLabels(labels: Labels, defaultValue = '', withoutBraces?: boolean): string {
if (!labels || Object.keys(labels).length === 0) {
return defaultValue;
}
const labelKeys = Object.keys(labels).sort();
const cleanSelector = labelKeys.map((key) => `${key}="${labels[key]}"`).join(', ');
if (withoutBraces) {
return cleanSelector;
}
return ['{', cleanSelector, '}'].join('');
}