Alerting: Add LogicOr operation option (#89258)

---------

Co-authored-by: brendamuir <100768211+brendamuir@users.noreply.github.com>
This commit is contained in:
Lu Shueh Chou
2024-08-16 11:02:14 -04:00
committed by GitHub
co-authored by brendamuir
parent 62abaea8f5
commit 126169f3ca
9 changed files with 77 additions and 11 deletions
+14 -5
View File
@@ -79,6 +79,11 @@ func (cmd *ConditionsCmd) Execute(ctx context.Context, t time.Time, vars mathexp
// matches contains the list of matches for all conditions
matches := make([]EvalMatch, 0)
for i, cond := range cmd.Conditions {
// Avoid operate subsequent conditions for LogicOr when it is already firing, see #87483
if isFiring && cond.Operator == ConditionOperatorLogicOr {
break
}
isCondFiring, isCondNoData, condMatches, err := cmd.executeCond(ctx, t, cond, vars)
if err != nil {
return mathexp.Results{}, err
@@ -221,7 +226,7 @@ func (cmd *ConditionsCmd) Type() string {
}
func compareWithOperator(b1, b2 bool, operator ConditionOperatorType) bool {
if operator == "or" {
if operator == ConditionOperatorOr || operator == ConditionOperatorLogicOr {
return b1 || b2
} else {
return b1 && b2
@@ -271,8 +276,9 @@ type ConditionEvalJSON struct {
type ConditionOperatorType string
const (
ConditionOperatorAnd ConditionOperatorType = "and"
ConditionOperatorOr ConditionOperatorType = "or"
ConditionOperatorAnd ConditionOperatorType = "and"
ConditionOperatorOr ConditionOperatorType = "or"
ConditionOperatorLogicOr ConditionOperatorType = "logic-or"
)
type ConditionOperatorJSON struct {
@@ -297,8 +303,11 @@ func NewConditionCmd(refID string, ccj []ConditionJSON) (*ConditionsCmd, error)
for i, cj := range ccj {
cond := condition{}
if i > 0 && cj.Operator.Type != "and" && cj.Operator.Type != "or" {
return nil, fmt.Errorf("condition %v operator must be `and` or `or`", i+1)
if i > 0 &&
cj.Operator.Type != ConditionOperatorAnd &&
cj.Operator.Type != ConditionOperatorOr &&
cj.Operator.Type != ConditionOperatorLogicOr {
return nil, fmt.Errorf("condition %v operator must be `and`, `or` or `logic-or`", i+1)
}
cond.Operator = cj.Operator.Type
+40
View File
@@ -595,6 +595,46 @@ func TestConditionsCmd(t *testing.T) {
v.SetMeta([]EvalMatch{{Value: util.Pointer(5.0)}, {Metric: "NoData"}})
return newResults(v)
},
}, {
name: "LogicOr will stop subsequent logic checks in condition: true AND true LogicOr false AND false",
vars: mathexp.Vars{
"A": mathexp.Results{
Values: []mathexp.Value{
newSeries(util.Pointer(1.0), util.Pointer(5.0)),
},
},
},
cmd: &ConditionsCmd{
Conditions: []condition{
{
InputRefID: "A",
Reducer: reducer("max"),
Evaluator: &thresholdEvaluator{Type: "gt", Threshold: 2},
},
{
InputRefID: "A",
Reducer: reducer("min"),
Operator: "and",
Evaluator: &thresholdEvaluator{Type: "gt", Threshold: 0},
},
{
InputRefID: "A",
Reducer: reducer("avg"),
Operator: "logic-or",
Evaluator: &thresholdEvaluator{Type: "gt", Threshold: 6},
},
{
InputRefID: "A",
Reducer: reducer("last"),
Operator: "and",
Evaluator: &thresholdEvaluator{Type: "gt", Threshold: 6},
},
}},
expected: func() mathexp.Results {
v := newNumber(util.Pointer(1.0))
v.SetMeta([]EvalMatch{{Value: util.Pointer(5.0)}, {Value: util.Pointer(1.0)}})
return newResults(v)
},
}}
for _, tt := range tests {
+2 -1
View File
@@ -525,7 +525,8 @@
"type": "string",
"enum": [
"and",
"or"
"or",
"logic-or"
],
"x-enum-description": {}
}
+2 -1
View File
@@ -559,7 +559,8 @@
"type": "string",
"enum": [
"and",
"or"
"or",
"logic-or"
],
"x-enum-description": {}
}
+3 -2
View File
@@ -228,7 +228,7 @@
{
"metadata": {
"name": "classic_conditions",
"resourceVersion": "1709915973363",
"resourceVersion": "1723675389127",
"creationTimestamp": "2024-02-21T22:09:26Z"
},
"spec": {
@@ -273,7 +273,8 @@
"type": {
"enum": [
"and",
"or"
"or",
"logic-or"
],
"type": "string",
"x-enum-description": {}