From 346a53145cbca79e65fc8d63db90357fa86d9764 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?G=C3=A1bor=20Farkas?= Date: Tue, 21 Sep 2021 15:19:52 +0200 Subject: [PATCH] prometheus: metadata: simplify the metrics-metadata format (#39411) * prometheus: metadata: simplify the metrics-metadata format * fixed unit test * fixed tests --- .../components/PrometheusMetricsBrowser.tsx | 2 +- .../monaco-query-field/MonacoQueryField.tsx | 2 +- .../prometheus/language_provider.ts | 2 +- .../prometheus/language_utils.test.ts | 43 ++++++----- .../datasource/prometheus/language_utils.ts | 77 +++++++++---------- .../datasource/prometheus/query_hints.test.ts | 2 +- .../datasource/prometheus/query_hints.ts | 2 +- .../plugins/datasource/prometheus/types.ts | 2 +- 8 files changed, 66 insertions(+), 66 deletions(-) diff --git a/public/app/plugins/datasource/prometheus/components/PrometheusMetricsBrowser.tsx b/public/app/plugins/datasource/prometheus/components/PrometheusMetricsBrowser.tsx index 6bbc052c310..3f93d2ab99c 100644 --- a/public/app/plugins/datasource/prometheus/components/PrometheusMetricsBrowser.tsx +++ b/public/app/plugins/datasource/prometheus/components/PrometheusMetricsBrowser.tsx @@ -404,7 +404,7 @@ export class UnthemedPrometheusMetricsBrowser extends React.Component { const getAllMetricNames = () => { const { metrics, metricsMetadata } = lpRef.current; const result = metrics.map((m) => { - const metaItem = metricsMetadata?.[m]?.[0]; + const metaItem = metricsMetadata?.[m]; return { name: m, help: metaItem?.help ?? '', diff --git a/public/app/plugins/datasource/prometheus/language_provider.ts b/public/app/plugins/datasource/prometheus/language_provider.ts index 40b2cd2c50e..5179cd24a7d 100644 --- a/public/app/plugins/datasource/prometheus/language_provider.ts +++ b/public/app/plugins/datasource/prometheus/language_provider.ts @@ -53,7 +53,7 @@ export function addHistoryMetadata(item: CompletionItem, history: any[]): Comple function addMetricsMetadata(metric: string, metadata?: PromMetricsMetadata): CompletionItem { const item: CompletionItem = { label: metric }; if (metadata && metadata[metric]) { - const { type, help } = metadata[metric][0]; + const { type, help } = metadata[metric]; item.documentation = `${type.toUpperCase()}: ${help}`; } return item; diff --git a/public/app/plugins/datasource/prometheus/language_utils.test.ts b/public/app/plugins/datasource/prometheus/language_utils.test.ts index a020c1166be..b6069383a6c 100644 --- a/public/app/plugins/datasource/prometheus/language_utils.test.ts +++ b/public/app/plugins/datasource/prometheus/language_utils.test.ts @@ -73,23 +73,25 @@ describe('parseSelector()', () => { describe('fixSummariesMetadata', () => { const synthetics = { - ALERTS: [ - { - type: 'counter', - 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.', - }, - ], + ALERTS: { + type: 'counter', + 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.', + }, }; it('returns only synthetics on empty metadata', () => { expect(fixSummariesMetadata({})).toEqual({ ...synthetics }); }); it('returns unchanged metadata if no summary is present', () => { - const metadata = { + const metadataRaw = { 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', () => { @@ -98,10 +100,10 @@ describe('fixSummariesMetadata', () => { bar: [{ type: 'summary', help: 'bar help' }], }; const expected = { - foo: [{ type: 'not_a_summary', help: 'foo 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_sum: [{ type: 'counter', help: 'Total sum of all observed values for the base metric (bar help)' }], + foo: { type: 'not_a_summary', help: 'foo 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_sum: { type: 'counter', help: 'Total sum of all observed values for the base metric (bar help)' }, }; expect(fixSummariesMetadata(metadata)).toEqual({ ...expected, ...synthetics }); }); @@ -112,13 +114,14 @@ describe('fixSummariesMetadata', () => { bar: [{ type: 'histogram', help: 'bar help' }], }; const expected = { - foo: [{ type: 'not_a_histogram', help: 'foo help' }], - bar: [{ type: 'histogram', help: 'bar help' }], - bar_bucket: [{ type: 'counter', help: 'Cumulative counters for the observation buckets (bar help)' }], - bar_count: [ - { 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)' }], + foo: { type: 'not_a_histogram', help: 'foo help' }, + bar: { type: 'histogram', help: 'bar help' }, + bar_bucket: { type: 'counter', help: 'Cumulative counters for the observation buckets (bar help)' }, + bar_count: { + 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)' }, }; expect(fixSummariesMetadata(metadata)).toEqual({ ...expected, ...synthetics }); }); diff --git a/public/app/plugins/datasource/prometheus/language_utils.ts b/public/app/plugins/datasource/prometheus/language_utils.ts index 4ec792a62cf..ba58c5d9673 100644 --- a/public/app/plugins/datasource/prometheus/language_utils.ts +++ b/public/app/plugins/datasource/prometheus/language_utils.ts @@ -1,4 +1,4 @@ -import { PromMetricsMetadata } from './types'; +import { PromMetricsMetadata, PromMetricsMetadataItem } from './types'; import { addLabelToQuery } from './add_label_to_query'; 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 */ -export function fixSummariesMetadata(metadata: PromMetricsMetadata): PromMetricsMetadata { +export function fixSummariesMetadata(metadata: { [metric: string]: PromMetricsMetadataItem[] }): PromMetricsMetadata { if (!metadata) { return metadata; } + const baseMetadata: PromMetricsMetadata = {}; const summaryMetadata: PromMetricsMetadata = {}; 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]; + baseMetadata[metric] = item; + if (item.type === 'histogram') { - summaryMetadata[`${metric}_bucket`] = [ - { - type: 'counter', - help: `Cumulative counters for the observation buckets (${item.help})`, - }, - ]; - summaryMetadata[`${metric}_count`] = [ - { - type: 'counter', - help: `Count of events that have been observed for the histogram metric (${item.help})`, - }, - ]; - summaryMetadata[`${metric}_sum`] = [ - { - type: 'counter', - help: `Total sum of all observed values for the histogram metric (${item.help})`, - }, - ]; + summaryMetadata[`${metric}_bucket`] = { + type: 'counter', + help: `Cumulative counters for the observation buckets (${item.help})`, + }; + summaryMetadata[`${metric}_count`] = { + type: 'counter', + help: `Count of events that have been observed 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') { - summaryMetadata[`${metric}_count`] = [ - { - type: 'counter', - help: `Count of events that have been observed for the base metric (${item.help})`, - }, - ]; - summaryMetadata[`${metric}_sum`] = [ - { - type: 'counter', - help: `Total sum of all observed values for the base metric (${item.help})`, - }, - ]; + summaryMetadata[`${metric}_count`] = { + type: 'counter', + help: `Count of events that have been observed for the base metric (${item.help})`, + }; + summaryMetadata[`${metric}_sum`] = { + type: 'counter', + help: `Total sum of all observed values for the base metric (${item.help})`, + }; } } // Synthetic series const syntheticMetadata: PromMetricsMetadata = {}; - syntheticMetadata['ALERTS'] = [ - { - type: 'counter', - 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.', - }, - ]; + syntheticMetadata['ALERTS'] = { + type: 'counter', + 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.', + }; - return { ...metadata, ...summaryMetadata, ...syntheticMetadata }; + return { ...baseMetadata, ...summaryMetadata, ...syntheticMetadata }; } export function roundMsToMin(milliseconds: number): number { diff --git a/public/app/plugins/datasource/prometheus/query_hints.test.ts b/public/app/plugins/datasource/prometheus/query_hints.test.ts index 1dbaf79082f..88948718049 100644 --- a/public/app/plugins/datasource/prometheus/query_hints.test.ts +++ b/public/app/plugins/datasource/prometheus/query_hints.test.ts @@ -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; let hints = getQueryHints('foo', series, datasource); diff --git a/public/app/plugins/datasource/prometheus/query_hints.ts b/public/app/plugins/datasource/prometheus/query_hints.ts index f9bcef45381..e49fe339b64 100644 --- a/public/app/plugins/datasource/prometheus/query_hints.ts +++ b/public/app/plugins/datasource/prometheus/query_hints.ts @@ -40,7 +40,7 @@ export function getQueryHints(query: string, series?: any[], datasource?: Promet counterNameMetric = metricMetadataKeys.find((metricName) => { // Only considering first type information, could be non-deterministic - const metadata = metricsMetadata[metricName][0]; + const metadata = metricsMetadata[metricName]; if (metadata.type.toLowerCase() === 'counter') { const metricRegex = new RegExp(`\\b${metricName}\\b`); if (query.match(metricRegex)) { diff --git a/public/app/plugins/datasource/prometheus/types.ts b/public/app/plugins/datasource/prometheus/types.ts index 4126d1e4980..fa84bcad94b 100644 --- a/public/app/plugins/datasource/prometheus/types.ts +++ b/public/app/plugins/datasource/prometheus/types.ts @@ -50,7 +50,7 @@ export interface PromMetricsMetadataItem { } export interface PromMetricsMetadata { - [metric: string]: PromMetricsMetadataItem[]; + [metric: string]: PromMetricsMetadataItem; } export interface PromDataSuccessResponse {