Skip to content

Commit 0e85ae0

Browse files
authored
Add support for rule group labels (#6665)
* Add support for rule group labels Signed-off-by: Mustafain Ali Khan <[email protected]> * fix test Signed-off-by: Mustafain Ali Khan <[email protected]> * Include group labels in backup and update integration test Signed-off-by: Mustafain Ali Khan <[email protected]> --------- Signed-off-by: Mustafain Ali Khan <[email protected]>
1 parent 1ca73a6 commit 0e85ae0

File tree

7 files changed

+156
-44
lines changed

7 files changed

+156
-44
lines changed

CHANGELOG.md

+1
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
* [FEATURE] Ingester/StoreGateway: Add `ResourceMonitor` module in Cortex, and add `ResourceBasedLimiter` in Ingesters and StoreGateways. #6674
99
* [FEATURE] Ingester: Support out-of-order native histogram ingestion. It automatically enabled when `-ingester.out-of-order-time-window > 0` and `-blocks-storage.tsdb.enable-native-histograms=true`. #6626 #6663
1010
* [FEATURE] Ruler: Add support for percentage based sharding for rulers. #6680
11+
* [FEATURE] Ruler: Add support for group labels. #6665
1112
* [ENHANCEMENT] Querier: Support query parameters to metadata api (/api/v1/metadata) to allow user to limit metadata to return. #6681
1213
* [ENHANCEMENT] Ingester: Add a `cortex_ingester_active_native_histogram_series` metric to track # of active NH series. #6695
1314
* [ENHANCEMENT] Query Frontend: Add new limit `-frontend.max-query-response-size` for total query response size after decompression in query frontend. #6607

integration/ruler_test.go

+42-4
Original file line numberDiff line numberDiff line change
@@ -311,6 +311,16 @@ func testRulerAPIWithSharding(t *testing.T, enableRulesBackup bool) {
311311
expectedNames := make([]string, numRulesGroups)
312312
alertCount := 0
313313
evalInterval, _ := model.ParseDuration("1s")
314+
groupLabels := map[string]string{
315+
"group_label_1": "val1",
316+
"group_label_2": "val2",
317+
"duplicate_label": "group_val",
318+
}
319+
ruleLabels := map[string]string{
320+
"rule_label_1": "val1",
321+
"rule_label_2": "val2",
322+
"duplicate_label": "rule_val",
323+
}
314324
for i := 0; i < numRulesGroups; i++ {
315325
num := random.Intn(100)
316326
var ruleNode yaml.Node
@@ -319,26 +329,28 @@ func testRulerAPIWithSharding(t *testing.T, enableRulesBackup bool) {
319329
ruleNode.SetString(fmt.Sprintf("rule_%d", i))
320330
exprNode.SetString(strconv.Itoa(i))
321331
ruleName := fmt.Sprintf("test_%d", i)
322-
323332
expectedNames[i] = ruleName
324333
if num%2 == 0 {
325334
alertCount++
326335
ruleGroups[i] = rulefmt.RuleGroup{
327336
Name: ruleName,
328337
Interval: evalInterval,
329338
Rules: []rulefmt.RuleNode{{
330-
Alert: ruleNode,
331-
Expr: exprNode,
339+
Alert: ruleNode,
340+
Expr: exprNode,
341+
Labels: ruleLabels,
332342
}},
343+
Labels: groupLabels,
333344
}
334345
} else {
335346
ruleGroups[i] = rulefmt.RuleGroup{
336347
Name: ruleName,
337348
Interval: evalInterval,
338349
Rules: []rulefmt.RuleNode{{
339350
Record: ruleNode,
340-
Expr: exprNode,
351+
Labels: ruleLabels,
341352
}},
353+
Labels: groupLabels,
342354
}
343355
}
344356
}
@@ -487,6 +499,32 @@ func testRulerAPIWithSharding(t *testing.T, enableRulesBackup bool) {
487499
assert.Greater(t, alertsCount, 0, "Expected greater than 0 alerts but got %d", alertsCount)
488500
},
489501
},
502+
"Filter Rules and verify Group Labels exist": {
503+
filter: e2ecortex.RuleFilter{
504+
RuleType: "alert",
505+
},
506+
resultCheckFn: func(t assert.TestingT, ruleGroups []*ruler.RuleGroup) {
507+
for _, ruleGroup := range ruleGroups {
508+
rule := ruleGroup.Rules[0].(map[string]interface{})
509+
ruleType := rule["type"]
510+
assert.Equal(t, "alerting", ruleType, "Expected 'alerting' rule type but got %s", ruleType)
511+
responseJson, err := json.Marshal(rule)
512+
assert.NoError(t, err)
513+
ar := &alertingRule{}
514+
assert.NoError(t, json.Unmarshal(responseJson, ar))
515+
if !ar.LastEvaluation.IsZero() {
516+
// Labels will be merged only if groups are loaded to Prometheus rule manager
517+
assert.Equal(t, 5, len(ar.Labels))
518+
}
519+
for _, label := range ar.Labels {
520+
if label.Name == "duplicate_label" {
521+
// rule label should override group label
522+
assert.Equal(t, ruleLabels["duplicate_label"], label.Value)
523+
}
524+
}
525+
}
526+
},
527+
},
490528
}
491529
// For each test case, fetch the rules with configured filters, and ensure the results match.
492530
if enableRulesBackup {

pkg/ruler/ruler.go

+1
Original file line numberDiff line numberDiff line change
@@ -1257,6 +1257,7 @@ func (r *Ruler) ruleGroupListToGroupStateDesc(userID string, backupGroups rulesp
12571257
User: userID,
12581258
Limit: group.Limit,
12591259
QueryOffset: group.QueryOffset,
1260+
Labels: group.Labels,
12601261
},
12611262
// We are keeping default value for EvaluationTimestamp and EvaluationDuration since the backup is not evaluating
12621263
}

pkg/ruler/rulespb/compat.go

+2
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ func ToProto(user string, namespace string, rl rulefmt.RuleGroup) *RuleGroupDesc
2626
User: user,
2727
Limit: int64(rl.Limit),
2828
QueryOffset: queryOffset,
29+
Labels: cortexpb.FromLabelsToLabelAdapters(labels.FromMap(rl.Labels)),
2930
}
3031
return &rg
3132
}
@@ -60,6 +61,7 @@ func FromProto(rg *RuleGroupDesc) rulefmt.RuleGroup {
6061
Rules: make([]rulefmt.RuleNode, len(rg.GetRules())),
6162
Limit: int(rg.Limit),
6263
QueryOffset: queryOffset,
64+
Labels: cortexpb.FromLabelAdaptersToLabels(rg.Labels).Map(),
6365
}
6466

6567
for i, rl := range rg.GetRules() {

pkg/ruler/rulespb/compat_test.go

+1
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ func TestProto(t *testing.T) {
3535
Rules: rules,
3636
Interval: model.Duration(time.Minute),
3737
QueryOffset: &queryOffset,
38+
Labels: map[string]string{},
3839
}
3940

4041
desc := ToProto("test", "namespace", rg)

pkg/ruler/rulespb/rules.pb.go

+105-40
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

pkg/ruler/rulespb/rules.proto

+4
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,10 @@ message RuleGroupDesc {
3030
int64 limit =10;
3131
google.protobuf.Duration queryOffset = 11
3232
[(gogoproto.nullable) = true, (gogoproto.stdduration) = true];
33+
repeated cortexpb.LabelPair labels = 12 [
34+
(gogoproto.nullable) = false,
35+
(gogoproto.customtype) = "github.com/cortexproject/cortex/pkg/cortexpb.LabelAdapter"
36+
];
3337
}
3438

3539
// RuleDesc is a proto representation of a Prometheus Rule

0 commit comments

Comments
 (0)