Alerting: Improve showing nextEvaluationDate for rules (#65205) (#65227)

* Improve showing nextEvaluationDate for rules

Co-Authored-By: Konrad Lalik <konradlalik@gmail.com>

* Improve imports and comments

---------

Co-authored-by: Konrad Lalik <konradlalik@gmail.com>
(cherry picked from commit b90aed4fd7)
This commit is contained in:
Virginia Cepeda
2023-03-27 10:32:20 -03:00
committed by GitHub
parent bb3e08a0a1
commit 9bafdcb72a
2 changed files with 25 additions and 11 deletions
@@ -1,4 +1,5 @@
import { css, cx } from '@emotion/css';
import { isBefore, formatDuration } from 'date-fns';
import React, { FC, useCallback, useMemo } from 'react';
import {
@@ -16,8 +17,7 @@ import { CombinedRule } from 'app/types/unified-alerting';
import { DEFAULT_PER_PAGE_PAGINATION } from '../../../../../core/constants';
import { useHasRuler } from '../../hooks/useHasRuler';
import { Annotation } from '../../utils/constants';
import { isGrafanaRulerRule } from '../../utils/rules';
import { isNullDate } from '../../utils/time';
import { isGrafanaRulerRule, isGrafanaRulerRulePaused } from '../../utils/rules';
import { DynamicTable, DynamicTableColumnProps, DynamicTableItemProps } from '../DynamicTable';
import { DynamicTableWithGuidelines } from '../DynamicTableWithGuidelines';
import { ProvisioningBadge } from '../Provisioning';
@@ -116,21 +116,30 @@ function useColumns(showSummaryColumn: boolean, showGroupColumn: boolean, showNe
const { hasRuler, rulerRulesLoaded } = useHasRuler();
const calculateNextEvaluationDate = useCallback((rule: CombinedRule) => {
const isValidLastEvaluation =
rule.promRule?.lastEvaluation &&
!isNullDate(rule.promRule.lastEvaluation) &&
isValidDate(rule.promRule.lastEvaluation);
const isValidLastEvaluation = rule.promRule?.lastEvaluation && isValidDate(rule.promRule.lastEvaluation);
const isValidIntervalDuration = rule.group.interval && isValidDuration(rule.group.interval);
if (!isValidLastEvaluation || !isValidIntervalDuration) {
if (!isValidLastEvaluation || !isValidIntervalDuration || isGrafanaRulerRulePaused(rule)) {
return;
}
const lastEvaluationDate = Date.parse(rule.promRule?.lastEvaluation || '');
const intervalDuration = parseDuration(rule.group.interval!);
const lastEvaluationDate = Date.parse(rule.promRule?.lastEvaluation || '');
const nextEvaluationDate = addDurationToDate(lastEvaluationDate, intervalDuration);
//when `nextEvaluationDate` is a past date it means lastEvaluation was more than one evaluation interval ago.
//in this case we use the interval value to show a more generic estimate.
//See https://github.com/grafana/grafana/issues/65125
const isPastDate = isBefore(nextEvaluationDate, new Date());
if (isPastDate) {
return {
humanized: `within ${formatDuration(intervalDuration)}`,
fullDate: `within ${formatDuration(intervalDuration)}`,
};
}
return {
humanized: dateTime(nextEvaluationDate).locale('en').fromNow(true),
humanized: `in ${dateTime(nextEvaluationDate).locale('en').fromNow(true)}`,
fullDate: dateTimeFormat(nextEvaluationDate, { format: 'YYYY-MM-DD HH:mm:ss' }),
};
}, []);
@@ -212,9 +221,9 @@ function useColumns(showSummaryColumn: boolean, showGroupColumn: boolean, showNe
renderCell: ({ data: rule }) => {
const nextEvalInfo = calculateNextEvaluationDate(rule);
return (
nextEvalInfo?.fullDate && (
nextEvalInfo && (
<Tooltip placement="top" content={`${nextEvalInfo?.fullDate}`} theme="info">
<span>in {nextEvalInfo?.humanized}</span>
<span>{nextEvalInfo?.humanized}</span>
</Tooltip>
)
);
@@ -5,6 +5,7 @@ import {
Alert,
AlertingRule,
CloudRuleIdentifier,
CombinedRule,
CombinedRuleGroup,
GrafanaRuleIdentifier,
PrometheusRuleIdentifier,
@@ -52,6 +53,10 @@ export function isGrafanaRulerRule(rule?: RulerRuleDTO): rule is RulerGrafanaRul
return typeof rule === 'object' && 'grafana_alert' in rule;
}
export function isGrafanaRulerRulePaused(rule: CombinedRule) {
return rule.rulerRule && isGrafanaRulerRule(rule.rulerRule) && Boolean(rule.rulerRule.grafana_alert.is_paused);
}
export function alertInstanceKey(alert: Alert): string {
return JSON.stringify(alert.labels);
}