diff options
Diffstat (limited to 'lib/mauve')
-rw-r--r-- | lib/mauve/alert.rb | 64 | ||||
-rw-r--r-- | lib/mauve/alert_changed.rb | 14 | ||||
-rw-r--r-- | lib/mauve/alert_group.rb | 30 | ||||
-rw-r--r-- | lib/mauve/proto.rb | 4 |
4 files changed, 107 insertions, 5 deletions
diff --git a/lib/mauve/alert.rb b/lib/mauve/alert.rb index ab13736..1e94bde 100644 --- a/lib/mauve/alert.rb +++ b/lib/mauve/alert.rb @@ -101,6 +101,7 @@ module Mauve property :raised_at, EpochTime property :cleared_at, EpochTime property :updated_at, EpochTime + property :suppress_until, EpochTime property :acknowledged_at, EpochTime property :acknowledged_by, String, :lazy => false property :update_type, String, :lazy => false @@ -458,7 +459,8 @@ module Mauve self.will_raise_at = nil self.cleared_at = nil # Don't clear will_clear_at - self.update_type = "raised" if self.update_type.nil? or self.update_type != "changed" or self.original_attributes[Alert.properties[:update_type]] == "cleared" + self.update_type = "raised" if self.update_type.nil? or !self.acknowledged? + self.suppress_until = nil unless self.suppressed? or self.was_raised? end self.save @@ -490,13 +492,14 @@ module Mauve self.cleared_at = at if self.cleared_at.nil? self.will_clear_at = nil self.update_type = "cleared" + self.suppress_until = nil unless self.suppressed? or self.was_cleared? end if self.save # # Clear all reminders. # - self.changes.all(:remind_at.not => nil, :at.lte => at, :update_type => "raised").each do |ac| + self.changes.all(:remind_at.not => nil).each do |ac| ac.remind_at = nil ac.save end @@ -513,7 +516,7 @@ module Mauve false end end - + # The next time this alert should be polled, either to raise, clear, or # unacknowledge, or nil if nothing is due. # @@ -545,6 +548,25 @@ module Mauve !raised_at.nil? and (cleared_at.nil? or raised_at > cleared_at) end + # Was the alert raised before changes were made? + # + # @return [Boolean] + def was_raised? + was_raised_at = if original_attributes.has_key?(Alert.properties[:raised_at]) + original_attributes[Alert.properties[:raised_at]] + else + self.raised_at + end + + was_cleared_at = if original_attributes.has_key?(Alert.properties[:cleared_at]) + original_attributes[Alert.properties[:cleared_at]] + else + self.cleared_at + end + + !was_raised_at.nil? and (was_cleared_at.nil? or was_raised_at > was_cleared_at) + end + # Is the alert acknowledged? # # @return [Boolean] @@ -552,6 +574,17 @@ module Mauve !acknowledged_at.nil? end + # Was the alert acknowledged before the current changes? + # + # @return [Boolean] + def was_acknowledged? + if original_attributes.has_key?(Alert.properties[:acknowledged_at]) + !original_attributes[Alert.properties[:acknowledged_at]].nil? + else + self.acknowledged? + end + end + # Is the alert cleared? Cleared is just the opposite of raised. # # @return [Boolean] @@ -559,6 +592,20 @@ module Mauve !raised? end + # Was the alert cleared before the current changes? + # + # @return [Boolean] + def was_cleared? + !was_raised? + end + + # Is the alert suppressed? + # + # @return [Boolean] + def suppressed? + self.suppress_until.is_a?(Time) and self.suppress_until > Time.now + end + # Work out an array of extra people to notify. # # @return [Array] array of persons @@ -807,6 +854,17 @@ module Mauve alert_db.updated_at = reception_time + # + # The alert suppression time can be set by an update if + # + # * the alert is not already suppressed + # * the alert has changed state. + # + if !alert_db.suppressed? and + ((alert_db.was_raised? and !alert_db.raised?) or (alert_db.was_cleared? and !alert_db.cleared?)) + alert_db.suppress_until = Time.at(alert.suppress_until + time_offset) + end + if alert_db.raised? # # If we're acknowledged, just save. diff --git a/lib/mauve/alert_changed.rb b/lib/mauve/alert_changed.rb index 6f1a717..64aee7b 100644 --- a/lib/mauve/alert_changed.rb +++ b/lib/mauve/alert_changed.rb @@ -99,9 +99,19 @@ module Mauve end # - # Push this notifitcation onto the queue. + # Bail out if notifications for this alert have been suppressed. # - Server.notification_push([alert, Time.now]) + if alert.suppressed? + # + # Skip reminders if the alert is suppressed. + # + logger.info("Notifications suppressed until #{alert.suppressed_until} for #{alert.inspect}") + else + # + # Push this notifitcation onto the queue. + # + Server.notification_push([alert, Time.now]) + end # # Need to make sure this reminder is cleared. diff --git a/lib/mauve/alert_group.rb b/lib/mauve/alert_group.rb index 76c2e98..c6d278c 100644 --- a/lib/mauve/alert_group.rb +++ b/lib/mauve/alert_group.rb @@ -154,6 +154,36 @@ module Mauve end during_runners = [] + + # + # Bail out if notifications for this alert have been suppressed. + # + if alert.suppressed? + logger.info("Notifications suppressed until #{alert.suppress_until} for #{alert.inspect}") + + this_reminder = AlertChanged.first_or_new( + :alert_id => alert.id, + :person => self.name, + :remind_at.not => nil, + :was_relevant => false + ) + + this_reminder.level = level.to_s + this_reminder.at = at + + if this_reminder.update_type.nil? or + (alert.raised? and this_reminder.update_type == "CLEARED") or + (alert.cleared? and %w(RAISED ACKNOWLEDGED).include?(this_reminder.update_type)) + + this_reminder.update_type = alert.update_type + this_reminder.remind_at = alert.suppress_until + else + this_reminder.remind_at = nil + end + + return this_reminder.save + end + # # This is where we set the reminder -- i.e. on a per-alert-group basis. diff --git a/lib/mauve/proto.rb b/lib/mauve/proto.rb index 6c22609..5c00572 100644 --- a/lib/mauve/proto.rb +++ b/lib/mauve/proto.rb @@ -46,6 +46,9 @@ # // # optional uint32 importance = 7; # +# // Suppress any notifications about this alert until this UNIX time. +# // +# optional uint64 suppress_until = 8; # } # # // The AlertUpdate is the unit of communication from an alerting source; @@ -102,6 +105,7 @@ module Mauve optional :string, :summary, 5 optional :string, :detail, 6 optional :uint32, :importance, 7 + optional :uint64, :suppress_until, 8 end class AlertUpdate < ::Protobuf::Message defined_in __FILE__ |