notifier.go 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161
  1. package alerting
  2. import (
  3. "fmt"
  4. "github.com/grafana/grafana/pkg/bus"
  5. "github.com/grafana/grafana/pkg/components/simplejson"
  6. "github.com/grafana/grafana/pkg/log"
  7. m "github.com/grafana/grafana/pkg/models"
  8. "github.com/grafana/grafana/pkg/services/alerting/alertstates"
  9. )
  10. type NotifierImpl struct {
  11. log log.Logger
  12. }
  13. func NewNotifier() *NotifierImpl {
  14. return &NotifierImpl{
  15. log: log.New("alerting.notifier"),
  16. }
  17. }
  18. func (n *NotifierImpl) Notify(alertResult *AlertResult) {
  19. notifiers := n.getNotifiers(alertResult.AlertJob.Rule.OrgId, []int64{1, 2})
  20. for _, notifier := range notifiers {
  21. warn := alertResult.State == alertstates.Warn && notifier.SendWarning
  22. crit := alertResult.State == alertstates.Critical && notifier.SendCritical
  23. if warn || crit {
  24. n.log.Info("Sending notification", "state", alertResult.State, "type", notifier.Type)
  25. go notifier.Notifierr.Dispatch(alertResult)
  26. }
  27. }
  28. }
  29. type Notification struct {
  30. Name string
  31. Type string
  32. SendWarning bool
  33. SendCritical bool
  34. Notifierr NotificationDispatcher
  35. }
  36. type EmailNotifier struct {
  37. To string
  38. log log.Logger
  39. }
  40. func (this *EmailNotifier) Dispatch(alertResult *AlertResult) {
  41. this.log.Info("Sending email")
  42. cmd := &m.SendEmailCommand{
  43. Data: map[string]interface{}{
  44. "Description": alertResult.Description,
  45. "TriggeredAlerts": alertResult.TriggeredAlerts,
  46. },
  47. To: []string{this.To},
  48. Info: "Alert result",
  49. Massive: false,
  50. Template: "",
  51. }
  52. bus.Dispatch(cmd)
  53. }
  54. type WebhookNotifier struct {
  55. Url string
  56. User string
  57. Password string
  58. log log.Logger
  59. }
  60. func (this *WebhookNotifier) Dispatch(alertResult *AlertResult) {
  61. this.log.Info("Sending webhook")
  62. bodyJSON := simplejson.New()
  63. bodyJSON.Set("name", alertResult.AlertJob.Rule.Name)
  64. bodyJSON.Set("state", alertResult.State)
  65. bodyJSON.Set("trigged", alertResult.TriggeredAlerts)
  66. body, _ := bodyJSON.MarshalJSON()
  67. cmd := &m.SendWebhook{
  68. Url: this.Url,
  69. User: this.User,
  70. Password: this.Password,
  71. Body: string(body),
  72. }
  73. bus.Dispatch(cmd)
  74. }
  75. type NotificationDispatcher interface {
  76. Dispatch(alertResult *AlertResult)
  77. }
  78. func (n *NotifierImpl) getNotifiers(orgId int64, notificationGroups []int64) []*Notification {
  79. query := &m.GetAlertNotificationQuery{
  80. OrgID: orgId,
  81. Ids: notificationGroups,
  82. }
  83. err := bus.Dispatch(query)
  84. if err != nil {
  85. n.log.Error("Failed to read notifications", "error", err)
  86. }
  87. var result []*Notification
  88. for _, notification := range query.Result {
  89. not, err := NewNotificationFromDBModel(notification)
  90. if err == nil {
  91. result = append(result, not)
  92. }
  93. }
  94. return result
  95. }
  96. func NewNotificationFromDBModel(model *m.AlertNotification) (*Notification, error) {
  97. notifier, err := createNotifier(model.Type, model.Settings)
  98. if err != nil {
  99. return nil, err
  100. }
  101. return &Notification{
  102. Name: model.Name,
  103. Type: model.Type,
  104. Notifierr: notifier,
  105. SendCritical: !model.Settings.Get("ignoreCrit").MustBool(),
  106. SendWarning: !model.Settings.Get("ignoreWarn").MustBool(),
  107. }, nil
  108. }
  109. var createNotifier = func(notificationType string, settings *simplejson.Json) (NotificationDispatcher, error) {
  110. if notificationType == "email" {
  111. to := settings.Get("to").MustString()
  112. if to == "" {
  113. return nil, fmt.Errorf("Could not find to propertie in settings")
  114. }
  115. return &EmailNotifier{
  116. To: to,
  117. log: log.New("alerting.notification.email"),
  118. }, nil
  119. }
  120. url := settings.Get("url").MustString()
  121. if url == "" {
  122. return nil, fmt.Errorf("Could not find url propertie in settings")
  123. }
  124. return &WebhookNotifier{
  125. Url: url,
  126. User: settings.Get("user").MustString(),
  127. Password: settings.Get("password").MustString(),
  128. log: log.New("alerting.notification.webhook"),
  129. }, nil
  130. }