Alerting: Add rule_matcher filter to Prometheus rules API (#115297)

**What is this feature?**

Add `rule_matcher` filter to the Prometheus-compatible list rules API: `/api/prometheus/grafana/api/v1/rules`. It allows to filter rules by static labels (not by alert instance labels).

**Special notes:**
  - Equality (`=`) and inequality (`!=`) matchers are pushed down to the database. Regex matchers (`=~`, `!~`) are applied in-memory at the API layer.
  - SQLite: Uses GLOB pattern matching
  - MySQL / PostgreSQL: Use JSON functions to compare label values


---------

Co-authored-by: Konrad Lalik <konradlalik@gmail.com>
This commit is contained in:
Alexander Akhmetov
2025-12-16 14:13:50 +01:00
committed by GitHub
co-authored by Konrad Lalik
parent c7c1dd4ead
commit c0295d06a3
18 changed files with 1137 additions and 71 deletions
+15
View File
@@ -219,6 +219,7 @@ func (f *RuleStore) ListAlertRulesByGroup(_ context.Context, q *models.ListAlert
RuleUIDs: q.RuleUIDs,
ReceiverName: q.ReceiverName,
HasPrometheusRuleDefinition: q.HasPrometheusRuleDefinition,
LabelMatchers: q.LabelMatchers,
}
ruleList, err := f.listAlertRules(query)
@@ -355,6 +356,20 @@ func (f *RuleStore) listAlertRules(q *models.ListAlertRulesQuery) (models.RulesG
if q.ReceiverName != "" && (len(r.NotificationSettings) < 1 || r.NotificationSettings[0].Receiver != q.ReceiverName) {
continue
}
if len(q.LabelMatchers) > 0 {
matches := true
for _, m := range q.LabelMatchers {
if !m.Matches(r.Labels[m.Name]) {
matches = false
break
}
}
if !matches {
continue
}
}
copyR := models.CopyRule(r)
ruleList = append(ruleList, copyR)
}