The open and composable observability and data visualization platform. Visualize metrics, logs, and traces from multiple sources like Prometheus, Loki, Elasticsearch, InfluxDB, Postgres and many more.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 
grafana/pkg/expr/classic/evaluator.go

98 lines
2.1 KiB

package classic
import (
"fmt"
"github.com/grafana/grafana/pkg/expr/mathexp"
)
type evaluator interface {
Eval(mathexp.Number) bool
}
type noValueEvaluator struct{}
type thresholdEvaluator struct {
Type string
Threshold float64
}
type rangedEvaluator struct {
Type string
Lower float64
Upper float64
}
// 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
}