notifier.go 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160
  1. package alerting
  2. import (
  3. "errors"
  4. "fmt"
  5. "strings"
  6. "github.com/grafana/grafana/pkg/bus"
  7. "github.com/grafana/grafana/pkg/log"
  8. m "github.com/grafana/grafana/pkg/models"
  9. "github.com/grafana/grafana/pkg/setting"
  10. )
  11. type RootNotifier struct {
  12. NotifierBase
  13. log log.Logger
  14. }
  15. func NewRootNotifier() *RootNotifier {
  16. return &RootNotifier{
  17. log: log.New("alerting.notifier"),
  18. }
  19. }
  20. func (n *RootNotifier) Notify(context *AlertResultContext) {
  21. n.log.Info("Sending notifications for", "ruleId", context.Rule.Id)
  22. notifiers, err := n.getNotifiers(context.Rule.OrgId, context.Rule.Notifications)
  23. if err != nil {
  24. n.log.Error("Failed to read notifications", "error", err)
  25. return
  26. }
  27. for _, notifier := range notifiers {
  28. n.log.Info("Sending notification", "firing", context.Firing, "type", notifier.GetType())
  29. go notifier.Notify(context)
  30. }
  31. }
  32. func (n *RootNotifier) getNotifiers(orgId int64, notificationIds []int64) ([]Notifier, error) {
  33. query := &m.GetAlertNotificationsQuery{OrgId: orgId, Ids: notificationIds}
  34. if err := bus.Dispatch(query); err != nil {
  35. return nil, err
  36. }
  37. var result []Notifier
  38. for _, notification := range query.Result {
  39. if not, err := NewNotificationFromDBModel(notification); err != nil {
  40. return nil, err
  41. } else {
  42. result = append(result, not)
  43. }
  44. }
  45. return result, nil
  46. }
  47. type NotifierBase struct {
  48. Name string
  49. Type string
  50. }
  51. func (n *NotifierBase) GetType() string {
  52. return n.Type
  53. }
  54. type EmailNotifier struct {
  55. NotifierBase
  56. Addresses []string
  57. log log.Logger
  58. }
  59. func (this *EmailNotifier) Notify(context *AlertResultContext) {
  60. this.log.Info("Sending alert notification to", "addresses", this.Addresses)
  61. slugQuery := &m.GetDashboardSlugByIdQuery{Id: context.Rule.DashboardId}
  62. if err := bus.Dispatch(slugQuery); err != nil {
  63. this.log.Error("Failed to load dashboard", "error", err)
  64. return
  65. }
  66. ruleLink := fmt.Sprintf("%sdashboard/db/%s?fullscreen&edit&tab=alert&panelId=%d", setting.AppUrl, slugQuery.Result, context.Rule.PanelId)
  67. cmd := &m.SendEmailCommand{
  68. Data: map[string]interface{}{
  69. "RuleState": context.Rule.State,
  70. "RuleName": context.Rule.Name,
  71. "Severity": context.Rule.Severity,
  72. "RuleLink": ruleLink,
  73. },
  74. To: this.Addresses,
  75. Template: "alert_notification.html",
  76. }
  77. err := bus.Dispatch(cmd)
  78. if err != nil {
  79. this.log.Error("Failed to send alert notification email", "error", err)
  80. }
  81. }
  82. // type WebhookNotifier struct {
  83. // Url string
  84. // User string
  85. // Password string
  86. // log log.Logger
  87. // }
  88. //
  89. // func (this *WebhookNotifier) Dispatch(context *AlertResultContext) {
  90. // this.log.Info("Sending webhook")
  91. //
  92. // bodyJSON := simplejson.New()
  93. // bodyJSON.Set("name", context.AlertJob.Rule.Name)
  94. // bodyJSON.Set("state", context.State)
  95. // bodyJSON.Set("trigged", context.TriggeredAlerts)
  96. //
  97. // body, _ := bodyJSON.MarshalJSON()
  98. //
  99. // cmd := &m.SendWebhook{
  100. // Url: this.Url,
  101. // User: this.User,
  102. // Password: this.Password,
  103. // Body: string(body),
  104. // }
  105. //
  106. // bus.Dispatch(cmd)
  107. // }
  108. func NewNotificationFromDBModel(model *m.AlertNotification) (Notifier, error) {
  109. if model.Type == "email" {
  110. addressesString := model.Settings.Get("addresses").MustString()
  111. if addressesString == "" {
  112. return nil, fmt.Errorf("Could not find addresses in settings")
  113. }
  114. return &EmailNotifier{
  115. NotifierBase: NotifierBase{
  116. Name: model.Name,
  117. Type: model.Type,
  118. },
  119. Addresses: strings.Split(addressesString, "\n"),
  120. log: log.New("alerting.notification.email"),
  121. }, nil
  122. }
  123. return nil, errors.New("Unsupported notification type")
  124. // url := settings.Get("url").MustString()
  125. // if url == "" {
  126. // return nil, fmt.Errorf("Could not find url propertie in settings")
  127. // }
  128. //
  129. // return &WebhookNotifier{
  130. // Url: url,
  131. // User: settings.Get("user").MustString(),
  132. // Password: settings.Get("password").MustString(),
  133. // log: log.New("alerting.notification.webhook"),
  134. // }, nil
  135. }