grafana/pkg/services/alerting/eval_handler.go

82 lines
2.2 KiB
Go
Raw Normal View History

2016-07-27 09:29:28 -05:00
package alerting
import (
2016-11-17 03:28:17 -06:00
"strconv"
"strings"
2016-07-27 09:29:28 -05:00
"time"
"github.com/grafana/grafana/pkg/infra/log"
"github.com/grafana/grafana/pkg/infra/metrics"
"github.com/grafana/grafana/pkg/tsdb/legacydata"
2016-07-27 09:29:28 -05:00
)
// DefaultEvalHandler is responsible for evaluating the alert rule.
2016-07-27 09:29:28 -05:00
type DefaultEvalHandler struct {
log log.Logger
alertJobTimeout time.Duration
requestHandler legacydata.RequestHandler
2016-07-27 09:29:28 -05:00
}
// NewEvalHandler is the `DefaultEvalHandler` constructor.
func NewEvalHandler(requestHandler legacydata.RequestHandler) *DefaultEvalHandler {
2016-07-27 09:29:28 -05:00
return &DefaultEvalHandler{
log: log.New("alerting.evalHandler"),
alertJobTimeout: time.Second * 5,
requestHandler: requestHandler,
2016-07-27 09:29:28 -05:00
}
}
// Eval evaluated the alert rule.
2016-07-27 09:29:28 -05:00
func (e *DefaultEvalHandler) Eval(context *EvalContext) {
firing := true
noDataFound := true
conditionEvals := ""
2016-11-17 03:28:17 -06:00
for i := 0; i < len(context.Rule.Conditions); i++ {
condition := context.Rule.Conditions[i]
cr, err := condition.Eval(context, e.requestHandler)
if err != nil {
context.Error = err
}
2016-07-27 09:29:28 -05:00
// break if condition could not be evaluated
if context.Error != nil {
break
}
if i == 0 {
firing = cr.Firing
noDataFound = cr.NoDataFound
}
// calculating Firing based on operator
if cr.Operator == "or" {
firing = firing || cr.Firing
} else {
firing = firing && cr.Firing
2016-07-27 09:29:28 -05:00
}
// We cannot evaluate the expression when one or more conditions are missing data
// and so noDataFound should be true if at least one condition returns no data,
// irrespective of the operator.
noDataFound = noDataFound || cr.NoDataFound
2016-11-17 03:28:17 -06:00
if i > 0 {
conditionEvals = "[" + conditionEvals + " " + strings.ToUpper(cr.Operator) + " " + strconv.FormatBool(cr.Firing) + "]"
2016-11-17 03:28:17 -06:00
} else {
conditionEvals = strconv.FormatBool(firing)
2016-11-17 03:28:17 -06:00
}
context.EvalMatches = append(context.EvalMatches, cr.EvalMatches...)
context.AllMatches = append(context.AllMatches, cr.AllMatches...)
2016-07-27 09:29:28 -05:00
}
context.ConditionEvals = conditionEvals + " = " + strconv.FormatBool(firing)
context.Firing = firing
context.NoDataFound = noDataFound
2016-07-27 09:29:28 -05:00
context.EndTime = time.Now()
elapsedTime := context.EndTime.Sub(context.StartTime).Nanoseconds() / int64(time.Millisecond)
metrics.MAlertingExecutionTime.Observe(float64(elapsedTime))
2016-07-27 09:29:28 -05:00
}