func (s *Schedule) executeExpr(T miniprofiler.Timer, rh *RunHistory, a *conf.Alert, e *expr.Expr) (*expr.Results, error) { if e == nil { return nil, nil } results, _, err := e.Execute(rh.Context, rh.GraphiteContext, rh.Logstash, rh.Elastic, rh.InfluxConfig, rh.Cache, T, rh.Start, 0, a.UnjoinedOK, s.Search, s.Conf.AlertSquelched(a), s) return results, err }
func (s *Schedule) executeExpr(T miniprofiler.Timer, rh *RunHistory, a *conf.Alert, e *expr.Expr) (*expr.Results, error) { if e == nil { return nil, nil } providers := &expr.BosunProviders{ Cache: rh.Cache, Search: s.Search, Squelched: s.RuleConf.AlertSquelched(a), History: s, } results, _, err := e.Execute(rh.Backends, providers, T, rh.Start, 0, a.UnjoinedOK) return results, err }
func (c *Context) evalExpr(e *expr.Expr, filter bool, series bool, autods int) (expr.ResultSlice, string, error) { var err error if filter { e, err = expr.New(opentsdb.ReplaceTags(e.Text, c.State.Group), c.schedule.Conf.Funcs()) if err != nil { return nil, "", err } } if series && e.Root.Return() != parse.TypeSeriesSet { return nil, "", fmt.Errorf("need a series, got %T (%v)", e, e) } res, _, err := e.Execute(c.runHistory.Context, c.runHistory.GraphiteContext, c.runHistory.Logstash, c.runHistory.Cache, nil, c.runHistory.Start, autods, c.Alert.UnjoinedOK, c.schedule.Search, c.schedule.Conf.AlertSquelched(c.Alert), c.runHistory) if err != nil { return nil, "", fmt.Errorf("%s: %v", e, err) } return res.Results, e.String(), nil }
func (c *Context) evalExpr(e *expr.Expr, filter bool, series bool, autods int) (expr.ResultSlice, string, error) { var err error if filter { e, err = expr.New(opentsdb.ReplaceTags(e.Text, c.AlertKey.Group()), c.schedule.RuleConf.GetFuncs(c.schedule.SystemConf.EnabledBackends())) if err != nil { return nil, "", err } } if series && e.Root.Return() != models.TypeSeriesSet { return nil, "", fmt.Errorf("need a series, got %T (%v)", e, e) } providers := &expr.BosunProviders{ Cache: c.runHistory.Cache, Search: c.schedule.Search, Squelched: c.schedule.RuleConf.AlertSquelched(c.Alert), History: c.schedule, } res, _, err := e.Execute(c.runHistory.Backends, providers, nil, c.runHistory.Start, autods, c.Alert.UnjoinedOK) if err != nil { return nil, "", fmt.Errorf("%s: %v", e, err) } return res.Results, e.String(), nil }
func (s *Schedule) executeExpr(T miniprofiler.Timer, rh *RunHistory, a *conf.Alert, e *expr.Expr) (*expr.Results, error) { if e == nil { return nil, nil } results, _, err := e.Execute(rh.Context, rh.GraphiteContext, rh.Logstash, rh.Cache, T, rh.Start, 0, a.UnjoinedOK, s.Search, s.Conf.AlertSquelched(a), rh) if err != nil { ak := expr.NewAlertKey(a.Name, nil) rh.Events[ak] = &Event{ Status: StError, Error: &Result{ Result: &expr.Result{ Computations: []expr.Computation{ { Text: e.String(), Value: err.Error(), }, }, }, }, } return nil, err } return results, err }
func (s *Schedule) CheckExpr(T miniprofiler.Timer, rh *RunHistory, a *conf.Alert, e *expr.Expr, checkStatus models.Status, ignore models.AlertKeys) (alerts models.AlertKeys, err error) { if e == nil { return } defer func() { if err == nil { return } collect.Add("check.errs", opentsdb.TagSet{"metric": a.Name}, 1) slog.Errorln(err) }() results, err := s.executeExpr(T, rh, a, e) if err != nil { return nil, err } Loop: for _, r := range results.Results { if s.Conf.Squelched(a, r.Group) { continue } ak := models.NewAlertKey(a.Name, r.Group) for _, v := range ignore { if ak == v { continue Loop } } var n float64 n, err = valueToFloat(r.Value) if err != nil { return } event := rh.Events[ak] if event == nil { event = new(models.Event) rh.Events[ak] = event } result := &models.Result{ Computations: r.Computations, Value: models.Float(n), Expr: e.String(), } switch checkStatus { case models.StWarning: event.Warn = result case models.StCritical: event.Crit = result } status := checkStatus if math.IsNaN(n) { status = checkStatus } else if n == 0 { status = models.StNormal } if status != models.StNormal { alerts = append(alerts, ak) } if status > rh.Events[ak].Status { event.Status = status } } return }
func (s *Schedule) CheckExpr(T miniprofiler.Timer, rh *RunHistory, a *conf.Alert, e *expr.Expr, checkStatus Status, ignore expr.AlertKeys) (alerts expr.AlertKeys, err error) { if e == nil { return } defer func() { if err == nil { return } collect.Add("check.errs", opentsdb.TagSet{"metric": a.Name}, 1) slog.Errorln(err) }() results, err := s.executeExpr(T, rh, a, e) if err != nil { return nil, err } Loop: for _, r := range results.Results { if s.Conf.Squelched(a, r.Group) { continue } ak := expr.NewAlertKey(a.Name, r.Group) for _, v := range ignore { if ak == v { continue Loop } } var n float64 switch v := r.Value.(type) { case expr.Number: n = float64(v) case expr.Scalar: n = float64(v) default: err = fmt.Errorf("expected number or scalar") return } event := rh.Events[ak] if event == nil { event = new(Event) rh.Events[ak] = event } result := &Result{ Result: r, Expr: e.String(), } switch checkStatus { case StWarning: event.Warn = result case StCritical: event.Crit = result } status := checkStatus if math.IsNaN(n) { status = StError } else if n == 0 { status = StNormal } if status != StNormal { alerts = append(alerts, ak) } if status > rh.Events[ak].Status { event.Status = status } } return }
func (s *Schedule) CheckExpr(T miniprofiler.Timer, rh *RunHistory, a *conf.Alert, e *expr.Expr, checkStatus models.Status, ignore models.AlertKeys) (alerts models.AlertKeys, err error, cancelled bool) { if e == nil { return } defer func() { if err == nil { return } collect.Add("check.errs", opentsdb.TagSet{"metric": a.Name}, 1) slog.Errorln(err) }() type res struct { results *expr.Results error error } // See s.CheckAlert for an explanation of execution and cancellation with this channel rc := make(chan res, 1) var results *expr.Results go func() { results, err := s.executeExpr(T, rh, a, e) rc <- res{results, err} }() select { case res := <-rc: results = res.results err = res.error case <-s.runnerContext.Done(): return nil, nil, true } if err != nil { return } Loop: for _, r := range results.Results { if s.RuleConf.Squelched(a, r.Group) { continue } ak := models.NewAlertKey(a.Name, r.Group) for _, v := range ignore { if ak == v { continue Loop } } var n float64 n, err = valueToFloat(r.Value) if err != nil { return } event := rh.Events[ak] if event == nil { event = new(models.Event) rh.Events[ak] = event } result := &models.Result{ Computations: r.Computations, Value: models.Float(n), Expr: e.String(), } switch checkStatus { case models.StWarning: event.Warn = result case models.StCritical: event.Crit = result } status := checkStatus if math.IsNaN(n) { status = checkStatus } else if n == 0 { status = models.StNormal } if status != models.StNormal { alerts = append(alerts, ak) } if status > rh.Events[ak].Status { event.Status = status } } return }