Skip to content

Commit

Permalink
feat: inhibit with label pairs
Browse files Browse the repository at this point in the history
Signed-off-by: swoga <[email protected]>
  • Loading branch information
swoga committed Sep 14, 2023
1 parent 5ba9b9c commit d7e399f
Show file tree
Hide file tree
Showing 3 changed files with 90 additions and 14 deletions.
8 changes: 8 additions & 0 deletions config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -866,6 +866,8 @@ type InhibitRule struct {
// A set of labels that must be equal between the source and target alert
// for them to be a match.
Equal model.LabelNames `yaml:"equal,omitempty" json:"equal,omitempty"`
// EqualPairs defines a set of pairs that have to be equal in the source and target alert
EqualPairs []LabelPair `yaml:"equal_pairs,omitempty" json:"equal_pairs,omitempty"`
}

// UnmarshalYAML implements the yaml.Unmarshaler interface for InhibitRule.
Expand All @@ -890,6 +892,12 @@ func (r *InhibitRule) UnmarshalYAML(unmarshal func(interface{}) error) error {
return nil
}

// LabelPair defines a source / target label pair
type LabelPair struct {
SourceLabel model.LabelName `yaml:"source_label,omitempty" json:"source_label,omitempty"`
TargetLabel model.LabelName `yaml:"target_label,omitempty" json:"target_label,omitempty"`
}

// Receiver configuration provides configuration on how to contact a receiver.
type Receiver struct {
// A unique identifier for this receiver.
Expand Down
35 changes: 28 additions & 7 deletions inhibit/inhibit.go
Original file line number Diff line number Diff line change
Expand Up @@ -157,19 +157,29 @@ type InhibitRule struct {
// The set of Filters which define the group of target alerts (which are
// inhibited by the source alerts).
TargetMatchers labels.Matchers
// A set of label names whose label values need to be identical in source and
// A set of label name pairs whose label values need to be identical in source and
// target alerts in order for the inhibition to take effect.
Equal map[model.LabelName]struct{}
EqualPairs LabelPairs

// Cache of alerts matching source labels.
scache *store.Alerts
}

// LabelPairs defines a set of source / target label pairs
type LabelPairs []LabelPair

// LabelPair defines a source / target label pair
type LabelPair struct {
SourceLabel model.LabelName
TargetLabel model.LabelName
}

// NewInhibitRule returns a new InhibitRule based on a configuration definition.
func NewInhibitRule(cr config.InhibitRule) *InhibitRule {
var (
sourcem labels.Matchers
targetm labels.Matchers
pairs LabelPairs
)
// cr.SourceMatch will be deprecated. This for loop appends regex matchers.
for ln, lv := range cr.SourceMatch {
Expand Down Expand Up @@ -213,15 +223,26 @@ func NewInhibitRule(cr config.InhibitRule) *InhibitRule {
// We append the new-style matchers. This can be simplified once the deprecated matcher syntax is removed.
targetm = append(targetm, cr.TargetMatchers...)

equal := map[model.LabelName]struct{}{}
for _, ln := range cr.Equal {
equal[ln] = struct{}{}
pair := LabelPair{
SourceLabel: ln,
TargetLabel: ln,
}
pairs = append(pairs, pair)
}

for _, p := range cr.EqualPairs {
pair := LabelPair{
SourceLabel: p.SourceLabel,
TargetLabel: p.TargetLabel,
}
pairs = append(pairs, pair)
}

return &InhibitRule{
SourceMatchers: sourcem,
TargetMatchers: targetm,
Equal: equal,
EqualPairs: pairs,
scache: store.NewAlerts(),
}
}
Expand All @@ -237,8 +258,8 @@ Outer:
if a.Resolved() {
continue
}
for n := range r.Equal {
if a.Labels[n] != lset[n] {
for _, p := range r.EqualPairs {
if a.Labels[p.SourceLabel] != lset[p.TargetLabel] {
continue Outer
}
}
Expand Down
61 changes: 54 additions & 7 deletions inhibit/inhibit_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,10 +35,11 @@ func TestInhibitRuleHasEqual(t *testing.T) {

now := time.Now()
cases := []struct {
initial map[model.Fingerprint]*types.Alert
equal model.LabelNames
input model.LabelSet
result bool
initial map[model.Fingerprint]*types.Alert
equal model.LabelNames
equalPairs LabelPairs
input model.LabelSet
result bool
}{
{
// No source alerts at all.
Expand Down Expand Up @@ -118,16 +119,62 @@ func TestInhibitRuleHasEqual(t *testing.T) {
input: model.LabelSet{"a": "b"},
result: false,
},
{
// Equal label pair does match
initial: map[model.Fingerprint]*types.Alert{
1: {
Alert: model.Alert{
Labels: model.LabelSet{"a": "b"},
StartsAt: now.Add(-time.Minute),
EndsAt: now.Add(time.Hour),
},
},
},
equalPairs: LabelPairs{
{
SourceLabel: "a",
TargetLabel: "x",
},
},
input: model.LabelSet{"x": "b"},
result: true,
},
{
// Equal label pair does not match
initial: map[model.Fingerprint]*types.Alert{
1: {
Alert: model.Alert{
Labels: model.LabelSet{"a": "b"},
StartsAt: now.Add(-time.Minute),
EndsAt: now.Add(time.Hour),
},
},
},
equalPairs: LabelPairs{
{
SourceLabel: "a",
TargetLabel: "x",
},
},
input: model.LabelSet{"x": "c"},
result: false,
},
}

for _, c := range cases {
r := &InhibitRule{
Equal: map[model.LabelName]struct{}{},
scache: store.NewAlerts(),
EqualPairs: LabelPairs{},
scache: store.NewAlerts(),
}
for _, ln := range c.equal {
r.Equal[ln] = struct{}{}
pair := LabelPair{
SourceLabel: ln,
TargetLabel: ln,
}
r.EqualPairs = append(r.EqualPairs, pair)
}
r.EqualPairs = append(r.EqualPairs, c.equalPairs...)

for _, v := range c.initial {
r.scache.Set(v)
}
Expand Down

0 comments on commit d7e399f

Please sign in to comment.