diff --git a/web/ui/mantine-ui/src/pages/query/ExplainViews/Selector.tsx b/web/ui/mantine-ui/src/pages/query/ExplainViews/Selector.tsx index 1b71e3591d..ca575ca2f4 100644 --- a/web/ui/mantine-ui/src/pages/query/ExplainViews/Selector.tsx +++ b/web/ui/mantine-ui/src/pages/query/ExplainViews/Selector.tsx @@ -128,13 +128,28 @@ const matchingCriteriaList = ( const SelectorExplainView: FC = ({ node }) => { const baseMetricName = node.name.replace(/(_count|_sum|_bucket)$/, ""); const { lookbackDelta } = useSettings(); - const { data: metricMeta } = useSuspenseAPIQuery({ + + // Try to get metadata for the full unchanged metric name first. + const { data: fullMetricMeta } = useSuspenseAPIQuery({ + path: `/metadata`, + params: { + metric: node.name, + }, + }); + + // Also get prefix-stripped metric metadata in case the metadata only exists for + // the histogram / summary base metric name. + const { data: baseMetricMeta } = useSuspenseAPIQuery({ path: `/metadata`, params: { metric: baseMetricName, }, }); + // Determine which metadata to use. + const metricMeta = + fullMetricMeta.data[node.name] ?? baseMetricMeta.data[baseMetricName]; + return ( @@ -142,17 +157,13 @@ const SelectorExplainView: FC = ({ node }) => { selector - {metricMeta.data === undefined || - metricMeta.data[baseMetricName] === undefined || - metricMeta.data[baseMetricName].length < 1 ? ( + {metricMeta === undefined || metricMeta.length < 1 ? ( <>No metric metadata found. ) : ( <> - Metric help:{" "} - {metricMeta.data[baseMetricName][0].help} + Metric help: {metricMeta[0].help}
- Metric type:{" "} - {metricMeta.data[baseMetricName][0].type} + Metric type: {metricMeta[0].type} )}
@@ -161,7 +172,8 @@ const SelectorExplainView: FC = ({ node }) => { {node.type === nodeType.vectorSelector ? ( <> This node selects the latest (non-stale) sample value within the - last {lookbackDelta} + last{" "} + {lookbackDelta} ) : ( <> diff --git a/web/ui/mantine-ui/src/pages/query/MetricsExplorer/MetricsExplorer.tsx b/web/ui/mantine-ui/src/pages/query/MetricsExplorer/MetricsExplorer.tsx index 600dfbae02..9c33a3df75 100644 --- a/web/ui/mantine-ui/src/pages/query/MetricsExplorer/MetricsExplorer.tsx +++ b/web/ui/mantine-ui/src/pages/query/MetricsExplorer/MetricsExplorer.tsx @@ -1,11 +1,23 @@ import { FC, useMemo, useState } from "react"; import { useSuspenseAPIQuery } from "../../../api/api"; import { MetadataResult } from "../../../api/responseTypes/metadata"; -import { ActionIcon, CopyButton, Group, Stack, Table, TextInput } from "@mantine/core"; +import { + ActionIcon, + CopyButton, + Group, + Stack, + Table, + TextInput, +} from "@mantine/core"; import React from "react"; import { Fuzzy } from "@nexucis/fuzzy"; import sanitizeHTML from "sanitize-html"; -import { IconCheck, IconCodePlus, IconCopy, IconZoomCode } from "@tabler/icons-react"; +import { + IconCheck, + IconCodePlus, + IconCopy, + IconZoomCode, +} from "@tabler/icons-react"; import LabelsExplorer from "./LabelsExplorer"; import { useDebouncedValue } from "@mantine/hooks"; import classes from "./MetricsExplorer.module.css"; @@ -55,10 +67,17 @@ const MetricsExplorer: FC = ({ return getSearchMatches(debouncedFilterText, metricNames); }, [debouncedFilterText, metricNames]); - const getMeta = (m: string) => - data.data[m.replace(/(_count|_sum|_bucket)$/, "")] || [ - { help: "unknown", type: "unknown", unit: "unknown" }, - ]; + const getMeta = (m: string) => { + return ( + // First check if the full metric name has metadata (even if it has one of the + // histogram/summary suffixes, it may be a metric that is not following naming + // conventions, see https://github.com/prometheus/prometheus/issues/16907). + data.data[m] ?? + data.data[m.replace(/(_count|_sum|_bucket)$/, "")] ?? [ + { help: "unknown", type: "unknown", unit: "unknown" }, + ] + ); + }; if (selectedMetric !== null) { return ( diff --git a/web/ui/module/codemirror-promql/src/complete/hybrid.ts b/web/ui/module/codemirror-promql/src/complete/hybrid.ts index 05650a2952..207173fca5 100644 --- a/web/ui/module/codemirror-promql/src/complete/hybrid.ts +++ b/web/ui/module/codemirror-promql/src/complete/hybrid.ts @@ -664,9 +664,11 @@ export class HybridComplete implements CompleteStrategy { .then((metricMetadata) => { if (metricMetadata) { for (const [metricName, node] of metricCompletion) { - // For histograms and summaries, the metadata is only exposed for the base metric name, - // not separately for the _count, _sum, and _bucket time series. - const metadata = metricMetadata[metricName.replace(/(_count|_sum|_bucket)$/, '')]; + // First check if the full metric name has metadata (even if it has one of the + // histogram/summary suffixes, it may be a metric that is not following naming + // conventions, see https://github.com/prometheus/prometheus/issues/16907). + // Then fall back to the base metric name if full metadata doesn't exist. + const metadata = metricMetadata[metricName] ?? metricMetadata[metricName.replace(/(_count|_sum|_bucket)$/, '')]; if (metadata) { if (metadata.length > 1) { // it means the metricName has different possible helper and type