mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
Prometheus: Add metadata to metrics in Metrics browser (#34708)
* Prometheus: Add metadata to metrics in Metrics browser - use the available metadata to enhance the tooltip on metric items in the metrics browser - added meta info for histogram metrics (was missing before) - also added one for ALERTS * fix test
This commit is contained in:
@@ -17,6 +17,7 @@ export interface Props extends Omit<HTMLAttributes<HTMLElement>, 'onClick'> {
|
|||||||
searchTerm?: string;
|
searchTerm?: string;
|
||||||
value?: string;
|
value?: string;
|
||||||
facets?: number;
|
facets?: number;
|
||||||
|
title?: string;
|
||||||
onClick?: OnLabelClick;
|
onClick?: OnLabelClick;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -24,7 +25,7 @@ export interface Props extends Omit<HTMLAttributes<HTMLElement>, 'onClick'> {
|
|||||||
* TODO #33976: Create a common, shared component with public/app/plugins/datasource/loki/components/LokiLabel.tsx
|
* TODO #33976: Create a common, shared component with public/app/plugins/datasource/loki/components/LokiLabel.tsx
|
||||||
*/
|
*/
|
||||||
export const Label = forwardRef<HTMLElement, Props>(
|
export const Label = forwardRef<HTMLElement, Props>(
|
||||||
({ name, value, hidden, facets, onClick, className, loading, searchTerm, active, style, ...rest }, ref) => {
|
({ name, value, hidden, facets, onClick, className, loading, searchTerm, active, style, title, ...rest }, ref) => {
|
||||||
const theme = useTheme2();
|
const theme = useTheme2();
|
||||||
const styles = getLabelStyles(theme);
|
const styles = getLabelStyles(theme);
|
||||||
const searchWords = searchTerm ? [searchTerm] : [];
|
const searchWords = searchTerm ? [searchTerm] : [];
|
||||||
@@ -46,7 +47,7 @@ export const Label = forwardRef<HTMLElement, Props>(
|
|||||||
ref={ref}
|
ref={ref}
|
||||||
onClick={onLabelClick}
|
onClick={onLabelClick}
|
||||||
style={style}
|
style={style}
|
||||||
title={text}
|
title={title || text}
|
||||||
role="option"
|
role="option"
|
||||||
aria-selected={!!active}
|
aria-selected={!!active}
|
||||||
className={cx(
|
className={cx(
|
||||||
|
|||||||
@@ -36,6 +36,7 @@ interface BrowserState {
|
|||||||
interface FacettableValue {
|
interface FacettableValue {
|
||||||
name: string;
|
name: string;
|
||||||
selected?: boolean;
|
selected?: boolean;
|
||||||
|
details?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface SelectableLabel {
|
export interface SelectableLabel {
|
||||||
@@ -385,7 +386,19 @@ export class UnthemedPrometheusMetricsBrowser extends React.Component<BrowserPro
|
|||||||
rawValues = rawValues.slice(0, MAX_VALUE_COUNT);
|
rawValues = rawValues.slice(0, MAX_VALUE_COUNT);
|
||||||
this.setState({ error });
|
this.setState({ error });
|
||||||
}
|
}
|
||||||
const values: FacettableValue[] = rawValues.map((value) => ({ name: value }));
|
const values: FacettableValue[] = [];
|
||||||
|
const { metricsMetadata } = languageProvider;
|
||||||
|
for (const labelValue of rawValues) {
|
||||||
|
const value: FacettableValue = { name: labelValue };
|
||||||
|
// Adding type/help text to metrics
|
||||||
|
if (name === METRIC_LABEL && metricsMetadata) {
|
||||||
|
const meta = metricsMetadata[labelValue]?.[0];
|
||||||
|
if (meta) {
|
||||||
|
value.details = `(${meta.type}) ${meta.help}`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
values.push(value);
|
||||||
|
}
|
||||||
this.updateLabelState(name, { values, loading: false });
|
this.updateLabelState(name, { values, loading: false });
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error(error);
|
console.error(error);
|
||||||
@@ -498,6 +511,7 @@ export class UnthemedPrometheusMetricsBrowser extends React.Component<BrowserPro
|
|||||||
<PromLabel
|
<PromLabel
|
||||||
name={metrics!.name}
|
name={metrics!.name}
|
||||||
value={value?.name}
|
value={value?.name}
|
||||||
|
title={value.details}
|
||||||
active={value?.selected}
|
active={value?.selected}
|
||||||
onClick={this.onClickMetric}
|
onClick={this.onClickMetric}
|
||||||
searchTerm={metricSearchTerm}
|
searchTerm={metricSearchTerm}
|
||||||
|
|||||||
@@ -72,15 +72,24 @@ describe('parseSelector()', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
describe('fixSummariesMetadata', () => {
|
describe('fixSummariesMetadata', () => {
|
||||||
it('returns empty metadata', () => {
|
const synthetics = {
|
||||||
expect(fixSummariesMetadata({})).toEqual({});
|
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', () => {
|
it('returns unchanged metadata if no summary is present', () => {
|
||||||
const metadata = {
|
const metadata = {
|
||||||
foo: [{ type: 'not_a_summary', help: 'foo help' }],
|
foo: [{ type: 'not_a_summary', help: 'foo help' }],
|
||||||
};
|
};
|
||||||
expect(fixSummariesMetadata(metadata)).toEqual(metadata);
|
expect(fixSummariesMetadata(metadata)).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', () => {
|
||||||
@@ -94,7 +103,24 @@ describe('fixSummariesMetadata', () => {
|
|||||||
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);
|
expect(fixSummariesMetadata(metadata)).toEqual({ ...expected, ...synthetics });
|
||||||
|
});
|
||||||
|
|
||||||
|
it('returns metadata with added bucket/count/sum for a histogram', () => {
|
||||||
|
const metadata = {
|
||||||
|
foo: [{ type: 'not_a_histogram', help: 'foo help' }],
|
||||||
|
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)' }],
|
||||||
|
};
|
||||||
|
expect(fixSummariesMetadata(metadata)).toEqual({ ...expected, ...synthetics });
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -176,6 +176,26 @@ export function fixSummariesMetadata(metadata: PromMetricsMetadata): PromMetrics
|
|||||||
const summaryMetadata: PromMetricsMetadata = {};
|
const summaryMetadata: PromMetricsMetadata = {};
|
||||||
for (const metric in metadata) {
|
for (const metric in metadata) {
|
||||||
const item = metadata[metric][0];
|
const item = metadata[metric][0];
|
||||||
|
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})`,
|
||||||
|
},
|
||||||
|
];
|
||||||
|
}
|
||||||
if (item.type === 'summary') {
|
if (item.type === 'summary') {
|
||||||
summaryMetadata[`${metric}_count`] = [
|
summaryMetadata[`${metric}_count`] = [
|
||||||
{
|
{
|
||||||
@@ -191,7 +211,17 @@ export function fixSummariesMetadata(metadata: PromMetricsMetadata): PromMetrics
|
|||||||
];
|
];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return { ...metadata, ...summaryMetadata };
|
// 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.',
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
return { ...metadata, ...summaryMetadata, ...syntheticMetadata };
|
||||||
}
|
}
|
||||||
|
|
||||||
export function roundMsToMin(milliseconds: number): number {
|
export function roundMsToMin(milliseconds: number): number {
|
||||||
|
|||||||
Reference in New Issue
Block a user