mirror of
https://github.com/prometheus/prometheus.git
synced 2026-06-08 16:12:16 -04:00
Merge pull request #17282 from SRasaikar/srasaikar/Issue_#4510
rules: add unknown state for unevaluated alerting rules
This commit is contained in:
commit
da17fe5a9c
4 changed files with 33 additions and 6 deletions
|
|
@ -50,8 +50,10 @@ const (
|
|||
type AlertState int
|
||||
|
||||
const (
|
||||
// StateUnknown is the state of an alert that has not yet been evaluated.
|
||||
StateUnknown AlertState = iota
|
||||
// StateInactive is the state of an alert that is neither firing nor pending.
|
||||
StateInactive AlertState = iota
|
||||
StateInactive
|
||||
// StatePending is the state of an alert that has been active for less than
|
||||
// the configured threshold duration.
|
||||
StatePending
|
||||
|
|
@ -62,6 +64,8 @@ const (
|
|||
|
||||
func (s AlertState) String() string {
|
||||
switch s {
|
||||
case StateUnknown:
|
||||
return "unknown"
|
||||
case StateInactive:
|
||||
return "inactive"
|
||||
case StatePending:
|
||||
|
|
@ -530,10 +534,14 @@ func (r *AlertingRule) Eval(ctx context.Context, queryOffset time.Duration, ts t
|
|||
}
|
||||
|
||||
// State returns the maximum state of alert instances for this rule.
|
||||
// StateFiring > StatePending > StateInactive.
|
||||
// StateFiring > StatePending > StateInactive > StateUnknown.
|
||||
func (r *AlertingRule) State() AlertState {
|
||||
r.activeMtx.Lock()
|
||||
defer r.activeMtx.Unlock()
|
||||
// Check if the rule has been evaluated
|
||||
if r.evaluationTimestamp.Load().IsZero() {
|
||||
return StateUnknown
|
||||
}
|
||||
|
||||
maxState := StateInactive
|
||||
for _, a := range r.active {
|
||||
|
|
|
|||
|
|
@ -85,6 +85,8 @@ func TestAlertingRuleState(t *testing.T) {
|
|||
for i, test := range tests {
|
||||
rule := NewAlertingRule(test.name, nil, 0, 0, labels.EmptyLabels(), labels.EmptyLabels(), labels.EmptyLabels(), "", true, nil)
|
||||
rule.active = test.active
|
||||
// Set evaluation timestamp to simulate that the rule has been evaluated
|
||||
rule.SetEvaluationTimestamp(time.Now())
|
||||
got := rule.State()
|
||||
require.Equal(t, test.want, got, "test case %d unexpected AlertState, want:%d got:%d", i, test.want, got)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
type RuleState = "pending" | "firing" | "inactive";
|
||||
type RuleState = "pending" | "firing" | "inactive" | "unknown";
|
||||
|
||||
export interface Alert {
|
||||
labels: Record<string, string>;
|
||||
|
|
|
|||
|
|
@ -45,6 +45,7 @@ type AlertsPageData = {
|
|||
inactive: number;
|
||||
pending: number;
|
||||
firing: number;
|
||||
unknown: number;
|
||||
};
|
||||
groups: {
|
||||
name: string;
|
||||
|
|
@ -55,6 +56,7 @@ type AlertsPageData = {
|
|||
inactive: number;
|
||||
pending: number;
|
||||
firing: number;
|
||||
unknown: number;
|
||||
};
|
||||
rules: {
|
||||
rule: AlertingRule;
|
||||
|
|
@ -82,6 +84,7 @@ const buildAlertsPageData = (
|
|||
inactive: 0,
|
||||
pending: 0,
|
||||
firing: 0,
|
||||
unknown: 0,
|
||||
},
|
||||
groups: [],
|
||||
};
|
||||
|
|
@ -92,6 +95,7 @@ const buildAlertsPageData = (
|
|||
inactive: 0,
|
||||
pending: 0,
|
||||
firing: 0,
|
||||
unknown: 0,
|
||||
};
|
||||
|
||||
for (const r of group.rules) {
|
||||
|
|
@ -109,6 +113,10 @@ const buildAlertsPageData = (
|
|||
pageData.globalCounts.pending++;
|
||||
groupCounts.pending++;
|
||||
break;
|
||||
case "unknown":
|
||||
pageData.globalCounts.unknown++;
|
||||
groupCounts.unknown++;
|
||||
break;
|
||||
default:
|
||||
throw new Error(`Unknown rule state: ${r.state}`);
|
||||
}
|
||||
|
|
@ -239,6 +247,11 @@ export default function AlertsPage() {
|
|||
pending ({g.counts.pending})
|
||||
</Badge>
|
||||
)}
|
||||
{g.counts.unknown > 0 && (
|
||||
<Badge className={badgeClasses.healthUnknown}>
|
||||
unknown ({g.counts.unknown})
|
||||
</Badge>
|
||||
)}
|
||||
{g.counts.inactive > 0 && (
|
||||
<Badge className={badgeClasses.healthOk}>
|
||||
inactive ({g.counts.inactive})
|
||||
|
|
@ -285,7 +298,9 @@ export default function AlertsPage() {
|
|||
? panelClasses.panelHealthErr
|
||||
: r.counts.pending > 0
|
||||
? panelClasses.panelHealthWarn
|
||||
: panelClasses.panelHealthOk
|
||||
: r.rule.state === "unknown"
|
||||
? panelClasses.panelHealthUnknown
|
||||
: panelClasses.panelHealthOk
|
||||
}
|
||||
>
|
||||
<Accordion.Control
|
||||
|
|
@ -401,13 +416,15 @@ export default function AlertsPage() {
|
|||
<Stack mt="xs">
|
||||
<Group>
|
||||
<StateMultiSelect
|
||||
options={["inactive", "pending", "firing"]}
|
||||
options={["inactive", "pending", "firing", "unknown"]}
|
||||
optionClass={(o) =>
|
||||
o === "inactive"
|
||||
? badgeClasses.healthOk
|
||||
: o === "pending"
|
||||
? badgeClasses.healthWarn
|
||||
: badgeClasses.healthErr
|
||||
: o === "firing"
|
||||
? badgeClasses.healthErr
|
||||
: badgeClasses.healthUnknown
|
||||
}
|
||||
optionCount={(o) =>
|
||||
alertsPageData.globalCounts[
|
||||
|
|
|
|||
Loading…
Reference in a new issue