From 13854b6f2274a901e7b4fa0aa3bbecd09ba0bb9a Mon Sep 17 00:00:00 2001 From: Arve Knudsen Date: Tue, 13 Sep 2022 09:35:03 +0200 Subject: [PATCH] rules: Add parameter controlling the max number of alerts rules can generate Rule group parameter alert_limit controls the maximum number of alerts rules belonging to the group can generate. It's similar to the existing limit parameter, but doesn't affect recording rules. Signed-off-by: Arve Knudsen --- model/rulefmt/rulefmt.go | 1 + rules/manager.go | 19 ++++++++++++++++++- 2 files changed, 19 insertions(+), 1 deletion(-) diff --git a/model/rulefmt/rulefmt.go b/model/rulefmt/rulefmt.go index 7cfb2e9d18..5fdaacdddf 100644 --- a/model/rulefmt/rulefmt.go +++ b/model/rulefmt/rulefmt.go @@ -139,6 +139,7 @@ type RuleGroup struct { Interval model.Duration `yaml:"interval,omitempty"` EvaluationDelay *model.Duration `yaml:"evaluation_delay,omitempty"` Limit int `yaml:"limit,omitempty"` + AlertLimit int `yaml:"alert_limit,omitempty"` Rules []RuleNode `yaml:"rules"` SourceTenants []string `yaml:"source_tenants,omitempty"` } diff --git a/rules/manager.go b/rules/manager.go index 2fe65eb21c..22dc34b1ae 100644 --- a/rules/manager.go +++ b/rules/manager.go @@ -246,6 +246,7 @@ type Group struct { interval time.Duration evaluationDelay *time.Duration limit int + alertLimit int rules []Rule sourceTenants []string seriesInPreviousEval []map[string]labels.Labels // One per Rule. @@ -277,6 +278,7 @@ type GroupOptions struct { Name, File string Interval time.Duration Limit int + AlertLimit int Rules []Rule SourceTenants []string ShouldRestore bool @@ -310,6 +312,7 @@ func NewGroup(o GroupOptions) *Group { interval: o.Interval, evaluationDelay: o.EvaluationDelay, limit: o.Limit, + alertLimit: o.AlertLimit, rules: o.Rules, shouldRestore: o.ShouldRestore, opts: o.Opts, @@ -345,6 +348,9 @@ func (g *Group) Interval() time.Duration { return g.interval } // Limit returns the group's limit. func (g *Group) Limit() int { return g.limit } +// AlertLimit returns the group's alert limit. +func (g *Group) AlertLimit() int { return g.alertLimit } + // SourceTenants returns the source tenants for the group. // If it's empty or nil, then the owning user/tenant is considered to be the source tenant. func (g *Group) SourceTenants() []string { return g.sourceTenants } @@ -634,7 +640,13 @@ func (g *Group) Eval(ctx context.Context, ts time.Time) { g.metrics.EvalTotal.WithLabelValues(GroupKey(g.File(), g.Name())).Inc() - vector, err := rule.Eval(ctx, evaluationDelay, ts, g.opts.QueryFunc, g.opts.ExternalURL, g.Limit()) + limit := g.Limit() + if _, ok := rule.(*AlertingRule); ok { + if g.AlertLimit() > 0 { + limit = g.AlertLimit() + } + } + vector, err := rule.Eval(ctx, evaluationDelay, ts, g.opts.QueryFunc, g.opts.ExternalURL, limit) if err != nil { rule.SetHealth(HealthBad) rule.SetLastError(err) @@ -891,6 +903,10 @@ func (g *Group) Equals(ng *Group) bool { return false } + if g.alertLimit != ng.alertLimit { + return false + } + if len(g.rules) != len(ng.rules) { return false } @@ -1163,6 +1179,7 @@ func (m *Manager) LoadGroups( File: fn, Interval: itv, Limit: rg.Limit, + AlertLimit: rg.AlertLimit, Rules: rules, SourceTenants: rg.SourceTenants, ShouldRestore: shouldRestore,