mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
Alerting: Do not count rule health for totals (#89349)
This commit is contained in:
parent
ef921fee3d
commit
86ac40418d
@ -0,0 +1,69 @@
|
|||||||
|
import { totalFromStats } from './RuleStats';
|
||||||
|
|
||||||
|
describe('RuleStats', () => {
|
||||||
|
it('should count 0', () => {
|
||||||
|
expect(
|
||||||
|
totalFromStats({
|
||||||
|
alerting: 0,
|
||||||
|
error: 0,
|
||||||
|
inactive: 0,
|
||||||
|
nodata: 0,
|
||||||
|
paused: 0,
|
||||||
|
pending: 0,
|
||||||
|
recording: 0,
|
||||||
|
})
|
||||||
|
).toBe(0);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should count rules', () => {
|
||||||
|
expect(
|
||||||
|
totalFromStats({
|
||||||
|
alerting: 2,
|
||||||
|
error: 0,
|
||||||
|
inactive: 0,
|
||||||
|
nodata: 0,
|
||||||
|
paused: 0,
|
||||||
|
pending: 2,
|
||||||
|
recording: 2,
|
||||||
|
})
|
||||||
|
).toBe(6);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should not count rule health as a rule', () => {
|
||||||
|
expect(
|
||||||
|
totalFromStats({
|
||||||
|
alerting: 0,
|
||||||
|
error: 1,
|
||||||
|
inactive: 1,
|
||||||
|
nodata: 0,
|
||||||
|
paused: 0,
|
||||||
|
pending: 0,
|
||||||
|
recording: 0,
|
||||||
|
})
|
||||||
|
).toBe(1);
|
||||||
|
|
||||||
|
expect(
|
||||||
|
totalFromStats({
|
||||||
|
alerting: 0,
|
||||||
|
error: 0,
|
||||||
|
inactive: 0,
|
||||||
|
nodata: 1,
|
||||||
|
paused: 0,
|
||||||
|
pending: 0,
|
||||||
|
recording: 1,
|
||||||
|
})
|
||||||
|
).toBe(1);
|
||||||
|
|
||||||
|
expect(
|
||||||
|
totalFromStats({
|
||||||
|
alerting: 0,
|
||||||
|
error: 0,
|
||||||
|
inactive: 1,
|
||||||
|
nodata: 0,
|
||||||
|
paused: 1,
|
||||||
|
pending: 0,
|
||||||
|
recording: 0,
|
||||||
|
})
|
||||||
|
).toBe(1);
|
||||||
|
});
|
||||||
|
});
|
@ -1,4 +1,4 @@
|
|||||||
import { isUndefined, omitBy, sum } from 'lodash';
|
import { isUndefined, omitBy, pick, sum } from 'lodash';
|
||||||
import pluralize from 'pluralize';
|
import pluralize from 'pluralize';
|
||||||
import React, { Fragment } from 'react';
|
import React, { Fragment } from 'react';
|
||||||
|
|
||||||
@ -27,24 +27,12 @@ const emptyStats: Required<AlertGroupTotals> = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
export const RuleStats = ({ namespaces }: Props) => {
|
export const RuleStats = ({ namespaces }: Props) => {
|
||||||
const stats = { ...emptyStats };
|
const stats = statsFromNamespaces(namespaces);
|
||||||
|
const total = totalFromStats(stats);
|
||||||
// sum all totals for all namespaces
|
|
||||||
namespaces.forEach(({ groups }) => {
|
|
||||||
groups.forEach((group) => {
|
|
||||||
const groupTotals = omitBy(group.totals, isUndefined);
|
|
||||||
for (let key in groupTotals) {
|
|
||||||
// @ts-ignore
|
|
||||||
stats[key] += groupTotals[key];
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
const statsComponents = getComponentsFromStats(stats);
|
const statsComponents = getComponentsFromStats(stats);
|
||||||
const hasStats = Boolean(statsComponents.length);
|
const hasStats = Boolean(statsComponents.length);
|
||||||
|
|
||||||
const total = sum(Object.values(stats));
|
|
||||||
|
|
||||||
statsComponents.unshift(
|
statsComponents.unshift(
|
||||||
<Fragment key="total">
|
<Fragment key="total">
|
||||||
{total} {pluralize('rule', total)}
|
{total} {pluralize('rule', total)}
|
||||||
@ -66,6 +54,32 @@ interface RuleGroupStatsProps {
|
|||||||
group: CombinedRuleGroup;
|
group: CombinedRuleGroup;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function statsFromNamespaces(namespaces: CombinedRuleNamespace[]): AlertGroupTotals {
|
||||||
|
const stats = { ...emptyStats };
|
||||||
|
|
||||||
|
// sum all totals for all namespaces
|
||||||
|
namespaces.forEach(({ groups }) => {
|
||||||
|
groups.forEach((group) => {
|
||||||
|
const groupTotals = omitBy(group.totals, isUndefined);
|
||||||
|
for (let key in groupTotals) {
|
||||||
|
// @ts-ignore
|
||||||
|
stats[key] += groupTotals[key];
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
return stats;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function totalFromStats(stats: AlertGroupTotals): number {
|
||||||
|
// countable stats will pick only the states that indicate a single rule – health indicators like "error" and "nodata" should
|
||||||
|
// not be counted because they are already counted by their state
|
||||||
|
const countableStats = pick(stats, ['alerting', 'pending', 'inactive', 'recording']);
|
||||||
|
const total = sum(Object.values(countableStats));
|
||||||
|
|
||||||
|
return total;
|
||||||
|
}
|
||||||
|
|
||||||
export const RuleGroupStats = ({ group }: RuleGroupStatsProps) => {
|
export const RuleGroupStats = ({ group }: RuleGroupStatsProps) => {
|
||||||
const stats = group.totals;
|
const stats = group.totals;
|
||||||
const evaluationInterval = group?.interval;
|
const evaluationInterval = group?.interval;
|
||||||
|
Loading…
Reference in New Issue
Block a user