Alerting: Add error recovery during rule evaluations (#35450)
* Alerting: Eval recovery after query failure * Apply suggestions from code review
This commit is contained in:
@@ -5,10 +5,12 @@ package eval
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"runtime/debug"
|
||||
"sort"
|
||||
"time"
|
||||
|
||||
"github.com/grafana/grafana/pkg/expr/classic"
|
||||
"github.com/grafana/grafana/pkg/infra/log"
|
||||
"github.com/grafana/grafana/pkg/services/ngalert/models"
|
||||
|
||||
"github.com/grafana/grafana/pkg/setting"
|
||||
@@ -23,6 +25,7 @@ const alertingEvaluationTimeout = 30 * time.Second
|
||||
|
||||
type Evaluator struct {
|
||||
Cfg *setting.Cfg
|
||||
Log log.Logger
|
||||
}
|
||||
|
||||
// invalidEvalResultFormatError is an error for invalid format of the alert definition evaluation results.
|
||||
@@ -105,6 +108,7 @@ func (s State) String() string {
|
||||
type AlertExecCtx struct {
|
||||
OrgID int64
|
||||
ExpressionsEnabled bool
|
||||
Log log.Logger
|
||||
|
||||
Ctx context.Context
|
||||
}
|
||||
@@ -220,7 +224,19 @@ func executeCondition(ctx AlertExecCtx, c *models.Condition, now time.Time, data
|
||||
return result
|
||||
}
|
||||
|
||||
func executeQueriesAndExpressions(ctx AlertExecCtx, data []models.AlertQuery, now time.Time, dataService *tsdb.Service) (*backend.QueryDataResponse, error) {
|
||||
func executeQueriesAndExpressions(ctx AlertExecCtx, data []models.AlertQuery, now time.Time, dataService *tsdb.Service) (resp *backend.QueryDataResponse, err error) {
|
||||
defer func() {
|
||||
if e := recover(); e != nil {
|
||||
ctx.Log.Error("alert rule panic", "error", e, "stack", string(debug.Stack()))
|
||||
panicErr := fmt.Errorf("alert rule panic; please check the logs for the full stack")
|
||||
if err != nil {
|
||||
err = fmt.Errorf("queries and expressions execution failed: %w; %v", err, panicErr.Error())
|
||||
} else {
|
||||
err = panicErr
|
||||
}
|
||||
}
|
||||
}()
|
||||
|
||||
queryDataReq, err := GetExprRequest(ctx, data, now)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -410,7 +426,7 @@ func (e *Evaluator) ConditionEval(condition *models.Condition, now time.Time, da
|
||||
alertCtx, cancelFn := context.WithTimeout(context.Background(), alertingEvaluationTimeout)
|
||||
defer cancelFn()
|
||||
|
||||
alertExecCtx := AlertExecCtx{OrgID: condition.OrgID, Ctx: alertCtx, ExpressionsEnabled: e.Cfg.ExpressionsEnabled}
|
||||
alertExecCtx := AlertExecCtx{OrgID: condition.OrgID, Ctx: alertCtx, ExpressionsEnabled: e.Cfg.ExpressionsEnabled, Log: e.Log}
|
||||
|
||||
execResult := executeCondition(alertExecCtx, condition, now, dataService)
|
||||
|
||||
@@ -423,7 +439,7 @@ func (e *Evaluator) QueriesAndExpressionsEval(orgID int64, data []models.AlertQu
|
||||
alertCtx, cancelFn := context.WithTimeout(context.Background(), alertingEvaluationTimeout)
|
||||
defer cancelFn()
|
||||
|
||||
alertExecCtx := AlertExecCtx{OrgID: orgID, Ctx: alertCtx, ExpressionsEnabled: e.Cfg.ExpressionsEnabled}
|
||||
alertExecCtx := AlertExecCtx{OrgID: orgID, Ctx: alertCtx, ExpressionsEnabled: e.Cfg.ExpressionsEnabled, Log: e.Log}
|
||||
|
||||
execResult, err := executeQueriesAndExpressions(alertExecCtx, data, now, dataService)
|
||||
if err != nil {
|
||||
|
||||
Reference in New Issue
Block a user