aboutsummaryrefslogtreecommitdiff
path: root/lib/mauve
diff options
context:
space:
mode:
authorPatrick J Cherry <patrick@bytemark.co.uk>2012-11-29 10:18:57 +0000
committerPatrick J Cherry <patrick@bytemark.co.uk>2012-11-29 10:18:57 +0000
commitb5d3d793deedd60ebd5dda9056d012ae3a9411a8 (patch)
tree7863c34f6dda4de768cb718d8cb31ec25f53f5a7 /lib/mauve
parent63ebee3b7ce56b49f6c545a4bc095c2f7499b7b8 (diff)
Added alert suppression to the server code + protobuf.
Diffstat (limited to 'lib/mauve')
-rw-r--r--lib/mauve/alert.rb64
-rw-r--r--lib/mauve/alert_changed.rb14
-rw-r--r--lib/mauve/alert_group.rb30
-rw-r--r--lib/mauve/proto.rb4
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__