base.go 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167
  1. // Copyright 2019 Yunion
  2. //
  3. // Licensed under the Apache License, Version 2.0 (the "License");
  4. // you may not use this file except in compliance with the License.
  5. // You may obtain a copy of the License at
  6. //
  7. // http://www.apache.org/licenses/LICENSE-2.0
  8. //
  9. // Unless required by applicable law or agreed to in writing, software
  10. // distributed under the License is distributed on an "AS IS" BASIS,
  11. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. // See the License for the specific language governing permissions and
  13. // limitations under the License.
  14. package notifiers
  15. import (
  16. "context"
  17. "time"
  18. "yunion.io/x/log"
  19. "yunion.io/x/onecloud/pkg/apis/monitor"
  20. "yunion.io/x/onecloud/pkg/monitor/alerting"
  21. "yunion.io/x/onecloud/pkg/monitor/models"
  22. )
  23. // NotifierBase is the base implentation of a notifier
  24. type NotifierBase struct {
  25. Ctx context.Context
  26. Name string
  27. Type string
  28. Id string
  29. IsDefault bool
  30. SendReminder bool
  31. DisableResolveMessage bool
  32. Frequency time.Duration
  33. }
  34. // NewNotifierBase returns a new NotifierBase
  35. func NewNotifierBase(config alerting.NotificationConfig) NotifierBase {
  36. return NotifierBase{
  37. Ctx: config.Ctx,
  38. Id: config.Id,
  39. Name: config.Name,
  40. // IsDefault: config.IsDefault,
  41. Type: config.Type,
  42. SendReminder: config.SendReminder,
  43. DisableResolveMessage: config.DisableResolveMessage,
  44. Frequency: config.Frequency,
  45. }
  46. }
  47. // ShouldNotify checks this evaluation should send an alert notification
  48. func (n *NotifierBase) ShouldNotify(_ context.Context, evalCtx *alerting.EvalContext, state *models.SAlertnotification) bool {
  49. prevState := evalCtx.PrevAlertState
  50. newState := evalCtx.Rule.State
  51. if evalCtx.HasRecoveredMatches() {
  52. return true
  53. }
  54. // Do not notify if alert state is no_data
  55. if newState == monitor.AlertStateNoData {
  56. return false
  57. }
  58. if newState == monitor.AlertStatePending {
  59. return false
  60. }
  61. if newState == monitor.AlertStateAlerting {
  62. if prevState == monitor.AlertStateOK {
  63. return true
  64. }
  65. send, err := state.ShouldSendNotification()
  66. if err != nil {
  67. log.Errorf("Alertnotification ShouldSendNotification exec err:%v", err)
  68. return false
  69. }
  70. return send
  71. }
  72. // Only notify on state change
  73. if prevState == newState && !n.SendReminder {
  74. return false
  75. }
  76. if prevState == newState && n.SendReminder {
  77. // Do not notify if interval has not elapsed
  78. lastNotify := state.UpdatedAt
  79. // if state.UpdatedAt != 0 && lastNotify.Add(n.Frequency).After(time.Now()) {
  80. if lastNotify.Add(n.Frequency).After(time.Now()) {
  81. return false
  82. }
  83. // Do not notify if alert state is OK or pending even on repeated notify
  84. if newState == monitor.AlertStateOK || newState == monitor.AlertStatePending {
  85. return false
  86. }
  87. }
  88. okOrPending := newState == monitor.AlertStatePending || newState == monitor.AlertStateOK
  89. // Do not notify when new state is ok/pending when previous is unknown
  90. if prevState == monitor.AlertStateUnknown && okOrPending {
  91. return false
  92. }
  93. // Do not notify when we become OK from pending
  94. if prevState == monitor.AlertStatePending && okOrPending {
  95. return false
  96. }
  97. // Do not notify when we OK -> Pending
  98. if prevState == monitor.AlertStateOK && okOrPending {
  99. return false
  100. }
  101. // Do not notify if state pending and it have been updated last minute
  102. if state.GetState() == monitor.AlertNotificationStatePending {
  103. lastUpdated := state.UpdatedAt
  104. if lastUpdated.Add(1 * time.Minute).After(time.Now()) {
  105. return false
  106. }
  107. }
  108. // Do not notify when state is OK if DisableResolveMessage is set to true
  109. if newState == monitor.AlertStateOK && n.DisableResolveMessage {
  110. return false
  111. }
  112. return true
  113. }
  114. // GetType returns the notifier type.
  115. func (n *NotifierBase) GetType() string {
  116. return n.Type
  117. }
  118. // GetNotifierId returns the notifier `uid`.
  119. func (n *NotifierBase) GetNotifierId() string {
  120. return n.Id
  121. }
  122. // GetIsDefault returns true if the notifiers should
  123. // be used for all alerts.
  124. /*func (n *NotifierBase) GetIsDefault() bool {
  125. return n.IsDeault
  126. }*/
  127. // GetSendReminder returns true if reminders should be sent.
  128. func (n *NotifierBase) GetSendReminder() bool {
  129. return n.SendReminder
  130. }
  131. // GetDisableResolveMessage returns true if ok alert notifications
  132. // should be skipped.
  133. func (n *NotifierBase) GetDisableResolveMessage() bool {
  134. return n.DisableResolveMessage
  135. }
  136. // GetFrequency returns the frequency for how often
  137. // alerts should be evaluated.
  138. func (n *NotifierBase) GetFrequency() time.Duration {
  139. return n.Frequency
  140. }