From 8cd4ee232e45eb2e044916c5b679fbafbb375c8c Mon Sep 17 00:00:00 2001 From: Markus Opolka <7090372+martialblog@users.noreply.github.com> Date: Tue, 3 Mar 2026 15:53:18 +0100 Subject: [PATCH 1/2] Include active alert labels in alert subcommand --- cmd/alert.go | 13 +++++++++---- internal/alert/alert.go | 14 +++++++++++++- internal/alert/alert_test.go | 3 +-- 3 files changed, 23 insertions(+), 7 deletions(-) diff --git a/cmd/alert.go b/cmd/alert.go index f6a68f1..75dc87d 100644 --- a/cmd/alert.go +++ b/cmd/alert.go @@ -71,13 +71,18 @@ inactive = 0`, // We use the Rules endpoint since it contains // the state of inactive Alert Rules, unlike the Alert endpoint // Search requested Alert in all Groups and all Rules - alerts, err := c.API.Rules(ctx) - if err != nil { - check.ExitError(err) + alertrules, errR := c.API.Rules(ctx) + if errR != nil { + check.ExitError(errR) + } + + alerts, errA := c.API.Alerts(ctx) + if errA != nil { + check.ExitError(errA) } // Get all rules from all groups into a single list - rules := alert.FlattenRules(alerts.Groups, cliAlertConfig.Group) + rules := alert.FlattenRules(alertrules.Groups, cliAlertConfig.Group, alerts.Alerts) // If there are no rules we can exit early if len(rules) == 0 { diff --git a/internal/alert/alert.go b/internal/alert/alert.go index 841ab37..1d640c9 100644 --- a/internal/alert/alert.go +++ b/internal/alert/alert.go @@ -12,6 +12,10 @@ import ( "github.com/prometheus/common/model" ) +const ( + alertnameLabelKey = "alertname" +) + // Internal representation of Prometheus Rules. // Alert attribute will be used when iterating over multiple AlertingRules. type Rule struct { @@ -19,7 +23,7 @@ type Rule struct { Alert *v1.Alert } -func FlattenRules(groups []v1.RuleGroup, wantedGroups []string) []Rule { +func FlattenRules(groups []v1.RuleGroup, wantedGroups []string, alerts []v1.Alert) []Rule { // Flattens a list of RuleGroup containing a list of Rules into // a list of internal Alertingrules. var l int @@ -50,6 +54,14 @@ func FlattenRules(groups []v1.RuleGroup, wantedGroups []string) []Rule { // since RecodingRules can simply be queried. if _, ok := rl.(v1.AlertingRule); ok { r.AlertingRule = rl.(v1.AlertingRule) + // Merge labels from active alerts + for _, al := range alerts { + alertName := al.Labels[alertnameLabelKey] + if r.AlertingRule.Name == string(alertName) { + r.AlertingRule.Labels = r.AlertingRule.Labels.Merge(al.Labels) + } + } + rules = append(rules, r) } } diff --git a/internal/alert/alert_test.go b/internal/alert/alert_test.go index 0d3ca5b..ed689c3 100644 --- a/internal/alert/alert_test.go +++ b/internal/alert/alert_test.go @@ -226,9 +226,8 @@ func TestFlattenRules(t *testing.T) { }, } - fr := FlattenRules(rg, nil) + fr := FlattenRules(rg, nil, []v1.Alert{}) if len(fr) != 1 { t.Error("\nActual: ", fr) } - } From 98ce46530588e6dbd06c1b1931f886d6682d510e Mon Sep 17 00:00:00 2001 From: Markus Opolka <7090372+martialblog@users.noreply.github.com> Date: Tue, 3 Mar 2026 16:11:28 +0100 Subject: [PATCH 2/2] [squash] --- internal/alert/alert_test.go | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/internal/alert/alert_test.go b/internal/alert/alert_test.go index ed689c3..9fd25ac 100644 --- a/internal/alert/alert_test.go +++ b/internal/alert/alert_test.go @@ -183,6 +183,15 @@ func TestGetOutput(t *testing.T) { func TestFlattenRules(t *testing.T) { testTime := time.Now() + alerts := []v1.Alert{ + v1.Alert{ + Labels: model.LabelSet{ + "alertname": "HighRequestLatency", + "instance": "node01", + }, + }, + } + rg := []v1.RuleGroup{ { Name: "example", @@ -226,8 +235,9 @@ func TestFlattenRules(t *testing.T) { }, } - fr := FlattenRules(rg, nil, []v1.Alert{}) - if len(fr) != 1 { - t.Error("\nActual: ", fr) + actual := FlattenRules(rg, nil, alerts) + + if len(actual) != 1 { + t.Error("\nActual: ", actual) } }