Skip to content

Commit

Permalink
Add matchers filtering field to rules api (#6083)
Browse files Browse the repository at this point in the history
* Add matchers filtering field to rules api

Signed-off-by: Eunice Kim <kimeuni@amazon.com>

* Address comments

Signed-off-by: Eunice Kim <kimeuni@amazon.com>

* Address comments

Signed-off-by: Eunice Kim <kimeuni@amazon.com>

---------

Signed-off-by: Eunice Kim <kimeuni@amazon.com>
  • Loading branch information
euniceek authored Jul 16, 2024
1 parent 1c8ebe3 commit 527d25f
Show file tree
Hide file tree
Showing 6 changed files with 321 additions and 51 deletions.
3 changes: 2 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,12 @@
* [ENHANCEMENT] Upgrade go to 1.22.5 #6014 #6072
* [ENHANCEMENT] Ingester: Add a new experimental `-ingester.labels-string-interning-enabled` flag to enable string interning for metrics labels. #6057
* [ENHANCEMENT] Ingester: Add link to renew 10% of the ingesters tokens in the admin page. #6063
* [ENHANCEMENT] Ruler: Add support for filtering by `state` and `health` field on Rules API. #6040
* [ENHANCEMENT] Ruler: Add support for filtering by `match` field on Rules API. #6083
* [BUGFIX] Configsdb: Fix endline issue in db password. #5920
* [BUGFIX] Ingester: Fix `user` and `type` labels for the `cortex_ingester_tsdb_head_samples_appended_total` TSDB metric. #5952
* [BUGFIX] Querier: Enforce max query length check for `/api/v1/series` API even though `ignoreMaxQueryLength` is set to true. #6018
* [BUGFIX] Ingester: Fix issue with the minimize token generator where it was not taking in consideration the current ownerhip of an instance when generating extra tokens. #6062
* [ENHANCEMENT] Ruler: Add support for filtering by `state` and `health` field on Rules API. #6040

## 1.17.1 2024-05-20

Expand Down
8 changes: 8 additions & 0 deletions pkg/ruler/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -147,13 +147,21 @@ func (a *API) PrometheusRules(w http.ResponseWriter, req *http.Request) {
return
}

_, err = parseMatchersParam(req.Form["match[]"])
if err != nil {
level.Error(logger).Log("msg", "error parsing match query params", "err", err)
util_api.RespondError(logger, w, v1.ErrBadData, fmt.Sprintf("error parsing match params %s", err), http.StatusBadRequest)
return
}

rulesRequest := RulesRequest{
RuleNames: req.Form["rule_name[]"],
RuleGroupNames: req.Form["rule_group[]"],
Files: req.Form["file[]"],
Type: typ,
State: state,
Health: health,
Matchers: req.Form["match[]"],
}

w.Header().Set("Content-Type", "application/json")
Expand Down
58 changes: 58 additions & 0 deletions pkg/ruler/ruler.go
Original file line number Diff line number Diff line change
Expand Up @@ -884,6 +884,10 @@ func (r *Ruler) getLocalRules(userID string, rulesRequest RulesRequest, includeB
ruleType := rulesRequest.Type
alertState := rulesRequest.State
health := rulesRequest.Health
matcherSets, err := parseMatchersParam(rulesRequest.Matchers)
if err != nil {
return nil, errors.Wrap(err, "error parsing matcher values")
}

returnAlerts := ruleType == "" || ruleType == alertingRuleFilter
returnRecording := (ruleType == "" || ruleType == recordingRuleFilter) && alertState == ""
Expand Down Expand Up @@ -928,6 +932,9 @@ func (r *Ruler) getLocalRules(userID string, rulesRequest RulesRequest, includeB
if !returnByHealth(health, string(r.Health())) {
continue
}
if !matchesMatcherSets(matcherSets, r.Labels()) {
continue
}
lastError := ""
if r.LastError() != nil {
lastError = r.LastError().Error()
Expand Down Expand Up @@ -1009,6 +1016,7 @@ func (r *Ruler) getLocalRules(userID string, rulesRequest RulesRequest, includeB
fileSet,
returnAlerts,
returnRecording,
matcherSets,
})
if err != nil {
return nil, err
Expand All @@ -1023,6 +1031,7 @@ type groupListFilter struct {
fileSet map[string]struct{}
returnAlerts bool
returnRecording bool
matcherSets [][]*labels.Matcher
}

// ruleGroupListToGroupStateDesc converts rulespb.RuleGroupList to []*GroupStateDesc while accepting filters to control what goes to the
Expand Down Expand Up @@ -1068,6 +1077,9 @@ func (r *Ruler) ruleGroupListToGroupStateDesc(userID string, backupGroups rulesp
continue
}
}
if !matchesMatcherSets(filters.matcherSets, cortexpb.FromLabelAdaptersToLabels(r.Labels)) {
continue
}

var ruleDesc *RuleStateDesc
query, err := parser.ParseExpr(r.GetExpr())
Expand Down Expand Up @@ -1162,6 +1174,7 @@ func (r *Ruler) getShardedRules(ctx context.Context, userID string, rulesRequest
RuleGroupNames: rulesRequest.GetRuleGroupNames(),
Files: rulesRequest.GetFiles(),
Type: rulesRequest.GetType(),
Matchers: rulesRequest.GetMatchers(),
})

if err != nil {
Expand Down Expand Up @@ -1320,3 +1333,48 @@ func returnByState(requestState string, alertState string) bool {
func returnByHealth(requestHealth string, ruleHealth string) bool {
return requestHealth == "" || requestHealth == ruleHealth
}

func parseMatchersParam(matchers []string) ([][]*labels.Matcher, error) {
var matcherSets [][]*labels.Matcher
for _, s := range matchers {
matchers, err := parser.ParseMetricSelector(s)
if err != nil {
return nil, err
}
matcherSets = append(matcherSets, matchers)
}

OUTER:
for _, ms := range matcherSets {
for _, lm := range ms {
if lm != nil && !lm.Matches("") {
continue OUTER
}
}
return nil, errors.New("match[] must contain at least one non-empty matcher")
}
return matcherSets, nil
}

func matches(l labels.Labels, matchers ...*labels.Matcher) bool {
for _, m := range matchers {
if v := l.Get(m.Name); !m.Matches(v) {
return false
}
}
return true
}

// matchesMatcherSets ensures all matches in each matcher set are ANDed and the set of those is ORed.
func matchesMatcherSets(matcherSets [][]*labels.Matcher, l labels.Labels) bool {
if len(matcherSets) == 0 {
return true
}

for _, matchers := range matcherSets {
if matches(l, matchers...) {
return true
}
}
return false
}
166 changes: 116 additions & 50 deletions pkg/ruler/ruler.pb.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions pkg/ruler/ruler.proto
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ message RulesRequest {
string type = 4;
string state = 5;
string health = 6;
repeated string matchers = 7;
}

message RulesResponse {
Expand Down
Loading

0 comments on commit 527d25f

Please sign in to comment.