mirror of
https://github.com/grafana/grafana.git
synced 2024-12-01 21:19:28 -06:00
402dc5e4d6
This pull request re-applies the refactoring of ConditionsCmd from a reverted fix #56812 for mathexp.noData. It does not add the fix, or tests for the fix, because those were added in #56816. We use the additional test coverage added in #56816 and #58650 to avoid the reoccurrence of regressions that caused us to revert #56812 the first time.
120 lines
2.4 KiB
Go
120 lines
2.4 KiB
Go
package classic
|
|
|
|
import (
|
|
"fmt"
|
|
|
|
"github.com/grafana/grafana/pkg/expr/mathexp"
|
|
)
|
|
|
|
type EvaluatorKind int
|
|
|
|
const (
|
|
EvaluatorNoValue = iota
|
|
EvaluatorThreshold
|
|
EvaluatorRanged
|
|
)
|
|
|
|
type evaluator interface {
|
|
Eval(mathexp.Number) bool
|
|
Kind() EvaluatorKind
|
|
}
|
|
|
|
type noValueEvaluator struct{}
|
|
|
|
func (noValueEvaluator) Kind() EvaluatorKind {
|
|
return EvaluatorNoValue
|
|
}
|
|
|
|
type thresholdEvaluator struct {
|
|
Type string
|
|
Threshold float64
|
|
}
|
|
|
|
func (thresholdEvaluator) Kind() EvaluatorKind {
|
|
return EvaluatorThreshold
|
|
}
|
|
|
|
type rangedEvaluator struct {
|
|
Type string
|
|
Lower float64
|
|
Upper float64
|
|
}
|
|
|
|
func (rangedEvaluator) Kind() EvaluatorKind {
|
|
return EvaluatorRanged
|
|
}
|
|
|
|
// newAlertEvaluator is a factory function for returning
|
|
// an AlertEvaluator depending on evaluation operator.
|
|
func newAlertEvaluator(model ConditionEvalJSON) (evaluator, error) {
|
|
switch model.Type {
|
|
case "gt", "lt":
|
|
return newThresholdEvaluator(model)
|
|
case "within_range", "outside_range":
|
|
return newRangedEvaluator(model)
|
|
case "no_value":
|
|
return &noValueEvaluator{}, nil
|
|
}
|
|
|
|
return nil, fmt.Errorf("evaluator invalid evaluator type: %s", model.Type)
|
|
}
|
|
|
|
func (e *thresholdEvaluator) Eval(reducedValue mathexp.Number) bool {
|
|
fv := reducedValue.GetFloat64Value()
|
|
if fv == nil {
|
|
return false
|
|
}
|
|
|
|
switch e.Type {
|
|
case "gt":
|
|
return *fv > e.Threshold
|
|
case "lt":
|
|
return *fv < e.Threshold
|
|
}
|
|
|
|
return false
|
|
}
|
|
|
|
func newThresholdEvaluator(model ConditionEvalJSON) (*thresholdEvaluator, error) {
|
|
if len(model.Params) == 0 {
|
|
return nil, fmt.Errorf("evaluator '%v' is missing the threshold parameter", model.Type)
|
|
}
|
|
|
|
return &thresholdEvaluator{
|
|
Type: model.Type,
|
|
Threshold: model.Params[0],
|
|
}, nil
|
|
}
|
|
|
|
func (e *noValueEvaluator) Eval(reducedValue mathexp.Number) bool {
|
|
return reducedValue.GetFloat64Value() == nil
|
|
}
|
|
|
|
func newRangedEvaluator(model ConditionEvalJSON) (*rangedEvaluator, error) {
|
|
if len(model.Params) != 2 {
|
|
return nil, fmt.Errorf("ranged evaluator requires 2 parameters")
|
|
}
|
|
|
|
return &rangedEvaluator{
|
|
Type: model.Type,
|
|
Lower: model.Params[0],
|
|
Upper: model.Params[1],
|
|
}, nil
|
|
}
|
|
|
|
func (e *rangedEvaluator) Eval(reducedValue mathexp.Number) bool {
|
|
fv := reducedValue.GetFloat64Value()
|
|
if fv == nil {
|
|
return false
|
|
}
|
|
|
|
switch e.Type {
|
|
case "within_range":
|
|
return (e.Lower < *fv && e.Upper > *fv) || (e.Upper < *fv && e.Lower > *fv)
|
|
case "outside_range":
|
|
return (e.Upper < *fv && e.Lower < *fv) || (e.Upper > *fv && e.Lower > *fv)
|
|
}
|
|
|
|
return false
|
|
}
|