evaluator.go 2.4 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697
  1. package conditions
  2. import (
  3. "encoding/json"
  4. "github.com/grafana/grafana/pkg/components/simplejson"
  5. "github.com/grafana/grafana/pkg/services/alerting"
  6. "github.com/grafana/grafana/pkg/tsdb"
  7. )
  8. var (
  9. defaultTypes []string = []string{"gt", "lt"}
  10. rangedTypes []string = []string{"within_range", "outside_range"}
  11. )
  12. type AlertEvaluator interface {
  13. Eval(timeSeries *tsdb.TimeSeries, reducedValue float64) bool
  14. }
  15. type DefaultAlertEvaluator struct {
  16. Type string
  17. Threshold float64
  18. }
  19. func (e *DefaultAlertEvaluator) Eval(series *tsdb.TimeSeries, reducedValue float64) bool {
  20. switch e.Type {
  21. case "gt":
  22. return reducedValue > e.Threshold
  23. case "lt":
  24. return reducedValue < e.Threshold
  25. }
  26. return false
  27. }
  28. type RangedAlertEvaluator struct {
  29. Type string
  30. Lower float64
  31. Upper float64
  32. }
  33. func (e *RangedAlertEvaluator) Eval(series *tsdb.TimeSeries, reducedValue float64) bool {
  34. switch e.Type {
  35. case "within_range":
  36. return (e.Lower < reducedValue && e.Upper > reducedValue) || (e.Upper < reducedValue && e.Lower > reducedValue)
  37. case "outside_range":
  38. return (e.Upper < reducedValue && e.Lower < reducedValue) || (e.Upper > reducedValue && e.Lower > reducedValue)
  39. }
  40. return false
  41. }
  42. func NewAlertEvaluator(model *simplejson.Json) (AlertEvaluator, error) {
  43. typ := model.Get("type").MustString()
  44. if typ == "" {
  45. return nil, alerting.ValidationError{Reason: "Evaluator missing type property"}
  46. }
  47. params := model.Get("params").MustArray()
  48. if len(params) == 0 {
  49. return nil, alerting.ValidationError{Reason: "Evaluator missing threshold parameter"}
  50. }
  51. firstParam, ok := params[0].(json.Number)
  52. if !ok {
  53. return nil, alerting.ValidationError{Reason: "Evaluator has invalid parameter"}
  54. }
  55. if inSlice(typ, defaultTypes) {
  56. defaultEval := &DefaultAlertEvaluator{Type: typ}
  57. defaultEval.Threshold, _ = firstParam.Float64()
  58. return defaultEval, nil
  59. }
  60. if inSlice(typ, rangedTypes) {
  61. secondParam, ok := params[1].(json.Number)
  62. if !ok {
  63. return nil, alerting.ValidationError{Reason: "Evaluator has invalid second parameter"}
  64. }
  65. rangedEval := &RangedAlertEvaluator{Type: typ}
  66. rangedEval.Lower, _ = firstParam.Float64()
  67. rangedEval.Upper, _ = secondParam.Float64()
  68. return rangedEval, nil
  69. }
  70. return nil, alerting.ValidationError{Reason: "Evaludator invalid evaluator type"}
  71. }
  72. func inSlice(a string, list []string) bool {
  73. for _, b := range list {
  74. if b == a {
  75. return true
  76. }
  77. }
  78. return false
  79. }