prometheus: metadata: simplify the metrics-metadata format (#39411)
* prometheus: metadata: simplify the metrics-metadata format * fixed unit test * fixed tests
This commit is contained in:
@@ -404,7 +404,7 @@ export class UnthemedPrometheusMetricsBrowser extends React.Component<BrowserPro
|
|||||||
const value: FacettableValue = { name: labelValue };
|
const value: FacettableValue = { name: labelValue };
|
||||||
// Adding type/help text to metrics
|
// Adding type/help text to metrics
|
||||||
if (name === METRIC_LABEL && metricsMetadata) {
|
if (name === METRIC_LABEL && metricsMetadata) {
|
||||||
const meta = metricsMetadata[labelValue]?.[0];
|
const meta = metricsMetadata[labelValue];
|
||||||
if (meta) {
|
if (meta) {
|
||||||
value.details = `(${meta.type}) ${meta.help}`;
|
value.details = `(${meta.type}) ${meta.help}`;
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -86,7 +86,7 @@ const MonacoQueryField = (props: Props) => {
|
|||||||
const getAllMetricNames = () => {
|
const getAllMetricNames = () => {
|
||||||
const { metrics, metricsMetadata } = lpRef.current;
|
const { metrics, metricsMetadata } = lpRef.current;
|
||||||
const result = metrics.map((m) => {
|
const result = metrics.map((m) => {
|
||||||
const metaItem = metricsMetadata?.[m]?.[0];
|
const metaItem = metricsMetadata?.[m];
|
||||||
return {
|
return {
|
||||||
name: m,
|
name: m,
|
||||||
help: metaItem?.help ?? '',
|
help: metaItem?.help ?? '',
|
||||||
|
|||||||
@@ -53,7 +53,7 @@ export function addHistoryMetadata(item: CompletionItem, history: any[]): Comple
|
|||||||
function addMetricsMetadata(metric: string, metadata?: PromMetricsMetadata): CompletionItem {
|
function addMetricsMetadata(metric: string, metadata?: PromMetricsMetadata): CompletionItem {
|
||||||
const item: CompletionItem = { label: metric };
|
const item: CompletionItem = { label: metric };
|
||||||
if (metadata && metadata[metric]) {
|
if (metadata && metadata[metric]) {
|
||||||
const { type, help } = metadata[metric][0];
|
const { type, help } = metadata[metric];
|
||||||
item.documentation = `${type.toUpperCase()}: ${help}`;
|
item.documentation = `${type.toUpperCase()}: ${help}`;
|
||||||
}
|
}
|
||||||
return item;
|
return item;
|
||||||
|
|||||||
@@ -73,23 +73,25 @@ describe('parseSelector()', () => {
|
|||||||
|
|
||||||
describe('fixSummariesMetadata', () => {
|
describe('fixSummariesMetadata', () => {
|
||||||
const synthetics = {
|
const synthetics = {
|
||||||
ALERTS: [
|
ALERTS: {
|
||||||
{
|
type: 'counter',
|
||||||
type: 'counter',
|
help:
|
||||||
help:
|
'Time series showing pending and firing alerts. The sample value is set to 1 as long as the alert is in the indicated active (pending or firing) state.',
|
||||||
'Time series showing pending and firing alerts. The sample value is set to 1 as long as the alert is in the indicated active (pending or firing) state.',
|
},
|
||||||
},
|
|
||||||
],
|
|
||||||
};
|
};
|
||||||
it('returns only synthetics on empty metadata', () => {
|
it('returns only synthetics on empty metadata', () => {
|
||||||
expect(fixSummariesMetadata({})).toEqual({ ...synthetics });
|
expect(fixSummariesMetadata({})).toEqual({ ...synthetics });
|
||||||
});
|
});
|
||||||
|
|
||||||
it('returns unchanged metadata if no summary is present', () => {
|
it('returns unchanged metadata if no summary is present', () => {
|
||||||
const metadata = {
|
const metadataRaw = {
|
||||||
foo: [{ type: 'not_a_summary', help: 'foo help' }],
|
foo: [{ type: 'not_a_summary', help: 'foo help' }],
|
||||||
};
|
};
|
||||||
expect(fixSummariesMetadata(metadata)).toEqual({ ...metadata, ...synthetics });
|
|
||||||
|
const metadata = {
|
||||||
|
foo: { type: 'not_a_summary', help: 'foo help' },
|
||||||
|
};
|
||||||
|
expect(fixSummariesMetadata(metadataRaw)).toEqual({ ...metadata, ...synthetics });
|
||||||
});
|
});
|
||||||
|
|
||||||
it('returns metadata with added count and sum for a summary', () => {
|
it('returns metadata with added count and sum for a summary', () => {
|
||||||
@@ -98,10 +100,10 @@ describe('fixSummariesMetadata', () => {
|
|||||||
bar: [{ type: 'summary', help: 'bar help' }],
|
bar: [{ type: 'summary', help: 'bar help' }],
|
||||||
};
|
};
|
||||||
const expected = {
|
const expected = {
|
||||||
foo: [{ type: 'not_a_summary', help: 'foo help' }],
|
foo: { type: 'not_a_summary', help: 'foo help' },
|
||||||
bar: [{ type: 'summary', help: 'bar help' }],
|
bar: { type: 'summary', help: 'bar help' },
|
||||||
bar_count: [{ type: 'counter', help: 'Count of events that have been observed for the base metric (bar help)' }],
|
bar_count: { type: 'counter', help: 'Count of events that have been observed for the base metric (bar help)' },
|
||||||
bar_sum: [{ type: 'counter', help: 'Total sum of all observed values for the base metric (bar help)' }],
|
bar_sum: { type: 'counter', help: 'Total sum of all observed values for the base metric (bar help)' },
|
||||||
};
|
};
|
||||||
expect(fixSummariesMetadata(metadata)).toEqual({ ...expected, ...synthetics });
|
expect(fixSummariesMetadata(metadata)).toEqual({ ...expected, ...synthetics });
|
||||||
});
|
});
|
||||||
@@ -112,13 +114,14 @@ describe('fixSummariesMetadata', () => {
|
|||||||
bar: [{ type: 'histogram', help: 'bar help' }],
|
bar: [{ type: 'histogram', help: 'bar help' }],
|
||||||
};
|
};
|
||||||
const expected = {
|
const expected = {
|
||||||
foo: [{ type: 'not_a_histogram', help: 'foo help' }],
|
foo: { type: 'not_a_histogram', help: 'foo help' },
|
||||||
bar: [{ type: 'histogram', help: 'bar help' }],
|
bar: { type: 'histogram', help: 'bar help' },
|
||||||
bar_bucket: [{ type: 'counter', help: 'Cumulative counters for the observation buckets (bar help)' }],
|
bar_bucket: { type: 'counter', help: 'Cumulative counters for the observation buckets (bar help)' },
|
||||||
bar_count: [
|
bar_count: {
|
||||||
{ type: 'counter', help: 'Count of events that have been observed for the histogram metric (bar help)' },
|
type: 'counter',
|
||||||
],
|
help: 'Count of events that have been observed for the histogram metric (bar help)',
|
||||||
bar_sum: [{ type: 'counter', help: 'Total sum of all observed values for the histogram metric (bar help)' }],
|
},
|
||||||
|
bar_sum: { type: 'counter', help: 'Total sum of all observed values for the histogram metric (bar help)' },
|
||||||
};
|
};
|
||||||
expect(fixSummariesMetadata(metadata)).toEqual({ ...expected, ...synthetics });
|
expect(fixSummariesMetadata(metadata)).toEqual({ ...expected, ...synthetics });
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { PromMetricsMetadata } from './types';
|
import { PromMetricsMetadata, PromMetricsMetadataItem } from './types';
|
||||||
import { addLabelToQuery } from './add_label_to_query';
|
import { addLabelToQuery } from './add_label_to_query';
|
||||||
import { SUGGESTIONS_LIMIT } from './language_provider';
|
import { SUGGESTIONS_LIMIT } from './language_provider';
|
||||||
|
|
||||||
@@ -169,59 +169,56 @@ function addLabelsToExpression(expr: string, invalidLabelsRegexp: RegExp) {
|
|||||||
*
|
*
|
||||||
* @param metadata HELP and TYPE metadata from /api/v1/metadata
|
* @param metadata HELP and TYPE metadata from /api/v1/metadata
|
||||||
*/
|
*/
|
||||||
export function fixSummariesMetadata(metadata: PromMetricsMetadata): PromMetricsMetadata {
|
export function fixSummariesMetadata(metadata: { [metric: string]: PromMetricsMetadataItem[] }): PromMetricsMetadata {
|
||||||
if (!metadata) {
|
if (!metadata) {
|
||||||
return metadata;
|
return metadata;
|
||||||
}
|
}
|
||||||
|
const baseMetadata: PromMetricsMetadata = {};
|
||||||
const summaryMetadata: PromMetricsMetadata = {};
|
const summaryMetadata: PromMetricsMetadata = {};
|
||||||
for (const metric in metadata) {
|
for (const metric in metadata) {
|
||||||
|
// NOTE: based on prometheus-documentation, we can receive
|
||||||
|
// multiple metadata-entries for the given metric, it seems
|
||||||
|
// it happens when the same metric is on multiple targets
|
||||||
|
// and their help-text differs
|
||||||
|
// (https://prometheus.io/docs/prometheus/latest/querying/api/#querying-metric-metadata)
|
||||||
|
// for now we just use the first entry.
|
||||||
const item = metadata[metric][0];
|
const item = metadata[metric][0];
|
||||||
|
baseMetadata[metric] = item;
|
||||||
|
|
||||||
if (item.type === 'histogram') {
|
if (item.type === 'histogram') {
|
||||||
summaryMetadata[`${metric}_bucket`] = [
|
summaryMetadata[`${metric}_bucket`] = {
|
||||||
{
|
type: 'counter',
|
||||||
type: 'counter',
|
help: `Cumulative counters for the observation buckets (${item.help})`,
|
||||||
help: `Cumulative counters for the observation buckets (${item.help})`,
|
};
|
||||||
},
|
summaryMetadata[`${metric}_count`] = {
|
||||||
];
|
type: 'counter',
|
||||||
summaryMetadata[`${metric}_count`] = [
|
help: `Count of events that have been observed for the histogram metric (${item.help})`,
|
||||||
{
|
};
|
||||||
type: 'counter',
|
summaryMetadata[`${metric}_sum`] = {
|
||||||
help: `Count of events that have been observed for the histogram metric (${item.help})`,
|
type: 'counter',
|
||||||
},
|
help: `Total sum of all observed values for the histogram metric (${item.help})`,
|
||||||
];
|
};
|
||||||
summaryMetadata[`${metric}_sum`] = [
|
|
||||||
{
|
|
||||||
type: 'counter',
|
|
||||||
help: `Total sum of all observed values for the histogram metric (${item.help})`,
|
|
||||||
},
|
|
||||||
];
|
|
||||||
}
|
}
|
||||||
if (item.type === 'summary') {
|
if (item.type === 'summary') {
|
||||||
summaryMetadata[`${metric}_count`] = [
|
summaryMetadata[`${metric}_count`] = {
|
||||||
{
|
type: 'counter',
|
||||||
type: 'counter',
|
help: `Count of events that have been observed for the base metric (${item.help})`,
|
||||||
help: `Count of events that have been observed for the base metric (${item.help})`,
|
};
|
||||||
},
|
summaryMetadata[`${metric}_sum`] = {
|
||||||
];
|
type: 'counter',
|
||||||
summaryMetadata[`${metric}_sum`] = [
|
help: `Total sum of all observed values for the base metric (${item.help})`,
|
||||||
{
|
};
|
||||||
type: 'counter',
|
|
||||||
help: `Total sum of all observed values for the base metric (${item.help})`,
|
|
||||||
},
|
|
||||||
];
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Synthetic series
|
// Synthetic series
|
||||||
const syntheticMetadata: PromMetricsMetadata = {};
|
const syntheticMetadata: PromMetricsMetadata = {};
|
||||||
syntheticMetadata['ALERTS'] = [
|
syntheticMetadata['ALERTS'] = {
|
||||||
{
|
type: 'counter',
|
||||||
type: 'counter',
|
help:
|
||||||
help:
|
'Time series showing pending and firing alerts. The sample value is set to 1 as long as the alert is in the indicated active (pending or firing) state.',
|
||||||
'Time series showing pending and firing alerts. The sample value is set to 1 as long as the alert is in the indicated active (pending or firing) state.',
|
};
|
||||||
},
|
|
||||||
];
|
|
||||||
|
|
||||||
return { ...metadata, ...summaryMetadata, ...syntheticMetadata };
|
return { ...baseMetadata, ...summaryMetadata, ...syntheticMetadata };
|
||||||
}
|
}
|
||||||
|
|
||||||
export function roundMsToMin(milliseconds: number): number {
|
export function roundMsToMin(milliseconds: number): number {
|
||||||
|
|||||||
@@ -42,7 +42,7 @@ describe('getQueryHints()', () => {
|
|||||||
],
|
],
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
const mock: unknown = { languageProvider: { metricsMetadata: { foo: [{ type: 'counter' }] } } };
|
const mock: unknown = { languageProvider: { metricsMetadata: { foo: { type: 'counter' } } } };
|
||||||
const datasource = mock as PrometheusDatasource;
|
const datasource = mock as PrometheusDatasource;
|
||||||
|
|
||||||
let hints = getQueryHints('foo', series, datasource);
|
let hints = getQueryHints('foo', series, datasource);
|
||||||
|
|||||||
@@ -40,7 +40,7 @@ export function getQueryHints(query: string, series?: any[], datasource?: Promet
|
|||||||
counterNameMetric =
|
counterNameMetric =
|
||||||
metricMetadataKeys.find((metricName) => {
|
metricMetadataKeys.find((metricName) => {
|
||||||
// Only considering first type information, could be non-deterministic
|
// Only considering first type information, could be non-deterministic
|
||||||
const metadata = metricsMetadata[metricName][0];
|
const metadata = metricsMetadata[metricName];
|
||||||
if (metadata.type.toLowerCase() === 'counter') {
|
if (metadata.type.toLowerCase() === 'counter') {
|
||||||
const metricRegex = new RegExp(`\\b${metricName}\\b`);
|
const metricRegex = new RegExp(`\\b${metricName}\\b`);
|
||||||
if (query.match(metricRegex)) {
|
if (query.match(metricRegex)) {
|
||||||
|
|||||||
@@ -50,7 +50,7 @@ export interface PromMetricsMetadataItem {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export interface PromMetricsMetadata {
|
export interface PromMetricsMetadata {
|
||||||
[metric: string]: PromMetricsMetadataItem[];
|
[metric: string]: PromMetricsMetadataItem;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface PromDataSuccessResponse<T = PromData> {
|
export interface PromDataSuccessResponse<T = PromData> {
|
||||||
|
|||||||
Reference in New Issue
Block a user