From ada66c90b081076579d28a9b1d3ec2767c63701f Mon Sep 17 00:00:00 2001 From: Patrick J Cherry Date: Wed, 1 May 2013 09:53:15 +0100 Subject: Allow alert to clear raised_at/cleared_at times if none specified --- lib/mauve/alert.rb | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'lib') diff --git a/lib/mauve/alert.rb b/lib/mauve/alert.rb index a2033a5..e6d1bae 100644 --- a/lib/mauve/alert.rb +++ b/lib/mauve/alert.rb @@ -850,6 +850,11 @@ module Mauve alert_db.raised_at = nil alert_db.will_raise_at = raise_time end + else + # + # If no raise time has been set, then update the database to reflect this. + # + alert_db.raised_at = alert_db.will_raise_at = nil end if clear_time @@ -863,6 +868,11 @@ module Mauve alert_db.cleared_at = nil alert_db.will_clear_at = clear_time end + else + # + # If no clear time has been set, then update the database to reflect this. + # + alert_db.cleared_at = alert_db.will_clear_at = nil end # -- cgit v1.2.1 From e9f52fa495d4e1e5dc0a3cc5fa51055372345147 Mon Sep 17 00:00:00 2001 From: Patrick J Cherry Date: Wed, 1 May 2013 09:53:50 +0100 Subject: Altered alert_group to only set one reminder. --- lib/mauve/alert_group.rb | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) (limited to 'lib') diff --git a/lib/mauve/alert_group.rb b/lib/mauve/alert_group.rb index fe78ad9..1889e64 100644 --- a/lib/mauve/alert_group.rb +++ b/lib/mauve/alert_group.rb @@ -236,15 +236,17 @@ module Mauve # OK got the next reminder time. # unless remind_at.nil? - this_reminder = AlertChanged.new( - :level => level.to_s, + this_reminder = AlertChanged.first_or_new( :alert_id => alert.id, :person => self.name, - :at => at, - :update_type => alert.update_type, - :remind_at => remind_at, - :was_relevant => true) + :remind_at.not => nil + ) + this_reminder.level = level.to_s + this_reminder.at = at + this_reminder.update_type = alert.update_type + this_reminder.remind_at => remind_at + this_reminder.was_relevant = true this_reminder.save end -- cgit v1.2.1 From 973afb547eeacc572b5834e6eaba513db4847f6e Mon Sep 17 00:00:00 2001 From: Patrick J Cherry Date: Wed, 1 May 2013 10:58:13 +0100 Subject: Fixed typo --- lib/mauve/alert_group.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib') diff --git a/lib/mauve/alert_group.rb b/lib/mauve/alert_group.rb index 1889e64..6126ed3 100644 --- a/lib/mauve/alert_group.rb +++ b/lib/mauve/alert_group.rb @@ -245,7 +245,7 @@ module Mauve this_reminder.level = level.to_s this_reminder.at = at this_reminder.update_type = alert.update_type - this_reminder.remind_at => remind_at + this_reminder.remind_at = remind_at this_reminder.was_relevant = true this_reminder.save end -- cgit v1.2.1 From 0267aaa13b2513cd40451932334ca72fbb62f2c0 Mon Sep 17 00:00:00 2001 From: Patrick J Cherry Date: Wed, 1 May 2013 11:53:12 +0100 Subject: Added conditions to prevent races. --- lib/mauve/alert_changed.rb | 2 +- lib/mauve/alert_group.rb | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) (limited to 'lib') diff --git a/lib/mauve/alert_changed.rb b/lib/mauve/alert_changed.rb index 2b9dfe5..6925085 100644 --- a/lib/mauve/alert_changed.rb +++ b/lib/mauve/alert_changed.rb @@ -110,7 +110,7 @@ module Mauve # # Push this notifitcation onto the queue. # - Server.notification_push([alert, Time.now]) + Server.notification_push([alert, self.remind_at]) end # diff --git a/lib/mauve/alert_group.rb b/lib/mauve/alert_group.rb index 6126ed3..424ba88 100644 --- a/lib/mauve/alert_group.rb +++ b/lib/mauve/alert_group.rb @@ -239,7 +239,8 @@ module Mauve this_reminder = AlertChanged.first_or_new( :alert_id => alert.id, :person => self.name, - :remind_at.not => nil + :remind_at.not => nil, + :remind_at.gt => at ) this_reminder.level = level.to_s -- cgit v1.2.1 From 344e58f4ca599e22fab7234b2c72080376dfa083 Mon Sep 17 00:00:00 2001 From: Patrick J Cherry Date: Wed, 1 May 2013 15:41:03 +0100 Subject: Further update to alert_group to find the last reminder for the same update type. --- lib/mauve/alert_group.rb | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'lib') diff --git a/lib/mauve/alert_group.rb b/lib/mauve/alert_group.rb index 424ba88..fe17516 100644 --- a/lib/mauve/alert_group.rb +++ b/lib/mauve/alert_group.rb @@ -236,16 +236,19 @@ module Mauve # OK got the next reminder time. # unless remind_at.nil? + # + # Find the last reminder, if available for the same alert, update type, and person. + # this_reminder = AlertChanged.first_or_new( :alert_id => alert.id, :person => self.name, + :update_type => alert.update_type, :remind_at.not => nil, :remind_at.gt => at ) this_reminder.level = level.to_s this_reminder.at = at - this_reminder.update_type = alert.update_type this_reminder.remind_at = remind_at this_reminder.was_relevant = true this_reminder.save -- cgit v1.2.1 From 4e457e94481a51e00eb174fa921620fb7ed00c83 Mon Sep 17 00:00:00 2001 From: Patrick J Cherry Date: Thu, 2 May 2013 14:27:48 +0100 Subject: Added lib --- lib/mauve/quick_update.rb | 166 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 166 insertions(+) create mode 100644 lib/mauve/quick_update.rb (limited to 'lib') diff --git a/lib/mauve/quick_update.rb b/lib/mauve/quick_update.rb new file mode 100644 index 0000000..d5ecc8a --- /dev/null +++ b/lib/mauve/quick_update.rb @@ -0,0 +1,166 @@ +# encoding: UTF-8 +require 'mauve/proto' +require 'mauve/sender' + +module Mauve + # + # This class can be used in simple cases where all the program needs to do is + # send an update about a single alert. + # + # In its simplest form, this could be something like + # + # Mauve::QuickUpdate.new("foo").raise! + # + # sends a "raise" to the default mauve destination about alert ID "foo". + # + # It can be used to do set more details about the alert. + # + # update = Mauve::QuickUpdate.new("foo") + # update.summary = "Foo backups failed" + # update.detail = cmd_output + # update.raise! + # + # Another example might be a heartbeat. + # + # update = Mauve::QuickUpdate.new("heartbeat") + # update.summary = "Heartbeat for this.host.name not received" + # update.detail = "Maybe this host is down, or if not, cron has stopped running." + # update.raise_at = Time.now + 600 + # update.clear_at = now + # update.suppress_until = Time.now + 900 + # update.send + # + class QuickUpdate + + def initialize(alert_id) + raise ArgumentError, "alert_id must be a String, or respond to to_s" unless alert_id.is_a?(String) or alert_id.respond_to?("to_s") + + @verbose = false + + @update = Mauve::Proto::AlertUpdate.new + @update.replace = false + @update.alert = [] + + @alert = Mauve::Proto::Alert.new + @alert.id = alert_id.to_s + + @update << @alert + end + + # + # Sets the replace flag for the whole update. Defaults to false. + # + def replace=(bool) + raise ArgumentError, "replace must either be true or false" unless bool.is_a?(TrueClass) or bool.is_a?(FalseClass) + + @update.replace = bool + end + + # + # Sets the verbose flag for the update process. Defaults to false. + # + def verbose=(bool) + raise ArgumentError, "verbose must either be true or false" unless bool.is_a?(TrueClass) or bool.is_a?(FalseClass) + + @verbose = bool + end + + # + # Sets the source of the alert. Defaults to the machine's hostname. + # + def source=(s) + raise ArgumentError, "source must be a String, or respond to to_s" unless s.is_a?(String) or s.respond_to?("to_s") + + @update.source = s.to_s + end + + # + # Sets the alert summary. Must be a string or something that can convert to a string. + # + def summary=(s) + raise ArgumentError, "summary must be a String, or respond to to_s" unless s.is_a?(String) or s.respond_to?("to_s") + + @alert.summary = s.to_s + end + + # + # Sets the alert detail. Must be a string or something that can convert to a string. + # + def detail=(s) + raise ArgumentError, "detail must be a String, or respond to to_s" unless s.is_a?(String) or s.respond_to?("to_s") + + @alert.detail = s + end + + # + # Sets the alert summary. Must be a string or something that can convert to a string. + # + def subject=(s) + raise ArgumentError, "subject must be a String, or respond to to_s" unless s.is_a?(String) or s.respond_to?("to_s") + + @alert.subject = s + end + + # + # Sets the raise time. Must be an Integer (epoch time) or a Time. + # + def raise_time=(t) + raise ArgumentError, "raise_time must be a Time or an Integer" unless t.is_a?(Time) or t.is_a?(Integer) + t = t.to_i if t.is_a?(Time) + + @alert.raise_time = t + end + + alias raise_at= raise_time= + + # + # Sets the clear time. Must be an Integer (epoch time) or a Time. + # + def clear_time=(t) + clear ArgumentError, "clear_time must be a Time or an Integer" unless t.is_a?(Time) or t.is_a?(Integer) + t = t.to_i if t.is_a?(Time) + + @alert.clear_time = t + end + + alias clear_at= clear_time= + + # + # Sets the time after which alerts will get sent. Must be an Integer (epoch time) or a Time. + # + def suppress_until=(t) + clear ArgumentError, "suppress_until must be a Time or an Integer" unless t.is_a?(Time) or t.is_a?(Integer) + t = t.to_i if t.is_a?(Time) + + @alert.suppress_until = t + end + + # + # Immediately send a raise message. The raise_time defaults to Time#now. + # + def raise!(t = Time.now) + self.raise_time = t + self.send + end + + # + # Immediately send a clear message. The clear_time defaults to Time#now. + # + def clear!(t = Time.now) + self.clear_time = t + self.send + end + + # + # This sends the alert. If destinations are left as nil, then the default + # as per Mauve::Sender are used. + # + def send(destinations = nil) + Mauve::Sender.new(destinations).send(@update, @verbose) + end + + end + +end + + -- cgit v1.2.1 From 829a59b0a2a0b470781b8ebd44481c02fb049421 Mon Sep 17 00:00:00 2001 From: Patrick J Cherry Date: Mon, 13 May 2013 12:32:57 +0100 Subject: Proto-supression calculation changes --- lib/mauve/person.rb | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) (limited to 'lib') diff --git a/lib/mauve/person.rb b/lib/mauve/person.rb index 979c0ab..3302ecc 100644 --- a/lib/mauve/person.rb +++ b/lib/mauve/person.rb @@ -114,7 +114,13 @@ module Mauve return self.notification_thresholds.any? do |period, previous_alert_times| # - # This is going to work out if we would be suppressed if + # This is going to work out if we would be suppressed if we send a notification now. + # + previous_alert_times = History.all(:user => self.username, + :type => "notification", + :created_at.gt => (now - period), + :event.like => '% succeeded') + if with_notification_at.nil? first = previous_alert_times.first last = previous_alert_times.last @@ -258,13 +264,13 @@ module Mauve # # Remember that we've sent an alert # - self.notification_thresholds.each do |period, previous_alert_times| + #self.notification_thresholds.each do |period, previous_alert_times| # # Hmm.. not sure how to make this thread-safe. # - self.notification_thresholds[period].push now - self.notification_thresholds[period].shift - end + # self.notification_thresholds[period].push now + # self.notification_thresholds[period].shift + #end return true -- cgit v1.2.1 From e08051b78bae61dd42b48f4f8d9d086823ddbd2a Mon Sep 17 00:00:00 2001 From: Patrick J Cherry Date: Tue, 14 May 2013 13:42:41 +0100 Subject: Database now queried to work out if a notification should be suppressed. --- lib/mauve/configuration_builders/person.rb | 15 ++++--- lib/mauve/notifiers/debug.rb | 2 +- lib/mauve/person.rb | 70 +++++++++++++----------------- 3 files changed, 42 insertions(+), 45 deletions(-) (limited to 'lib') diff --git a/lib/mauve/configuration_builders/person.rb b/lib/mauve/configuration_builders/person.rb index f171d10..9cc09ab 100644 --- a/lib/mauve/configuration_builders/person.rb +++ b/lib/mauve/configuration_builders/person.rb @@ -51,10 +51,15 @@ module Mauve def suppress_notifications_after(h) raise ArgumentError.new("notification_threshold must be specified as e.g. (10 => 1.minute)") unless h.kind_of?(Hash) - h.each do |k,v| - raise ArgumentError.new("notification_threshold must be specified as e.g. (10 => 1.minute)") unless k.is_a?(Integer) and v.is_a?(Integer) - - @result.notification_thresholds[v] = Array.new(k) + h.each do |number_of_alerts,in_period| + raise ArgumentError.new("notification_threshold must be specified as e.g. (10 => 1.minute)") unless number_of_alerts.is_a?(Integer) and in_period.is_a?(Integer) + + @result.suppress_notifications_after[in_period] = number_of_alerts + # History.all( + # :limit => number_of_alerts, + # :order => :created_at.desc, + # :type => "notification", + # :event.like => '% succeeded') end end @@ -87,7 +92,7 @@ module Mauve # # Add a default notification threshold # - person.notification_thresholds[600] = Array.new(5) if person.notification_thresholds.empty? + person.suppress_notifications_after[600] = 5 if person.suppress_notifications_after.empty? # # Add a default notify clause diff --git a/lib/mauve/notifiers/debug.rb b/lib/mauve/notifiers/debug.rb index a9afc52..b3e88e2 100644 --- a/lib/mauve/notifiers/debug.rb +++ b/lib/mauve/notifiers/debug.rb @@ -69,7 +69,7 @@ module Mauve deliver_to_queue << [Time.now, self.class, destination, message] if deliver_to_queue - if @disable_normal_delivery + if @disable_normal_delivery true # pretend it happened OK if we're just testing else send_alert_without_debug(destination, alert, all_alerts, conditions) diff --git a/lib/mauve/person.rb b/lib/mauve/person.rb index 3302ecc..1aa27ee 100644 --- a/lib/mauve/person.rb +++ b/lib/mauve/person.rb @@ -6,13 +6,12 @@ module Mauve class Person attr_reader :username, :password, :urgent, :normal, :low, :email, :xmpp, :sms - attr_reader :notification_thresholds, :last_pop3_login, :suppressed, :notifications + attr_reader :last_pop3_login, :suppressed, :notifications attr_reader :notify_when_off_sick, :notify_when_on_holiday # Set up a new Person # def initialize(username) - @notification_thresholds = nil @suppressed = false # # TODO fix up web login so pop3 can be used as a proxy. @@ -111,36 +110,45 @@ module Mauve # @param [Time] Current time. # @return [Boolean] If suppression is needed. def should_suppress?(with_notification_at = nil, now = Time.now) + # + # This is the query we use. It doesn't get polled until later. + # + previous_notifications = History.all(:order => :created_at.desc, :user => self.username, :type => "notification", :event.like => '% succeeded', :fields => [:created_at]) + + # + # Find the latest alert. + # + if with_notification_at.nil? + latest_notification = previous_notifications.first + latest = (latest_notification.nil? ? nil : latest_notification.created_at) + else + latest = with_notification_at + end - return self.notification_thresholds.any? do |period, previous_alert_times| + return self.suppress_notifications_after.any? do |period, number| # - # This is going to work out if we would be suppressed if we send a notification now. + # If no notification time has been specified, use the earliest alert time. # - previous_alert_times = History.all(:user => self.username, - :type => "notification", - :created_at.gt => (now - period), - :event.like => '% succeeded') - - if with_notification_at.nil? - first = previous_alert_times.first - last = previous_alert_times.last + if with_notification_at.nil? or number == 0 + earliest_notification = previous_notifications[number-1] else - first = previous_alert_times[1] - last = with_notification_at + earliest_notification = previous_notifications[number-2] end - - (first.is_a?(Time) and (now - first) < period) or - (last.is_a?(Time) and @suppressed and (now - last) < period) + + earliest = (earliest_notification.nil? ? nil : earliest_notification.created_at) + + (earliest.is_a?(Time) and (now - earliest) < period) or + (latest.is_a?(Time) and @suppressed and (now - latest) < period) end end - # The notification thresholds for this user # - # @return [Hash] - def notification_thresholds - @notification_thresholds ||= { } + # + # + def suppress_notifications_after + @suppress_notifications_after ||= { } end - + # This class implements an instance_eval context to execute the blocks # for running a notification block for each person. # @@ -260,23 +268,7 @@ module Mauve ).instance_eval(&__send__(level)) end - if [result].flatten.any? - # - # Remember that we've sent an alert - # - #self.notification_thresholds.each do |period, previous_alert_times| - # - # Hmm.. not sure how to make this thread-safe. - # - # self.notification_thresholds[period].push now - # self.notification_thresholds[period].shift - #end - - - return true - end - - return false + return [result].flatten.any? end # -- cgit v1.2.1 From 0119cfa4314a96409f3b0551904aa2af6e443e13 Mon Sep 17 00:00:00 2001 From: Patrick J Cherry Date: Thu, 16 May 2013 11:47:41 +0100 Subject: Updated Person#should_suppress to take into account alert level when deciding to suppress an alert. --- lib/mauve/person.rb | 85 +++++++++++++++++++++++++++++++++++++---------------- 1 file changed, 60 insertions(+), 25 deletions(-) (limited to 'lib') diff --git a/lib/mauve/person.rb b/lib/mauve/person.rb index 1aa27ee..eb6e28b 100644 --- a/lib/mauve/person.rb +++ b/lib/mauve/person.rb @@ -106,39 +106,74 @@ module Mauve # Works out if a notification should be suppressed. If no parameters are supplied, it will # + # @param [Symbol] Level of notification that is being tested # @param [Time] Theoretical time of notification # @param [Time] Current time. # @return [Boolean] If suppression is needed. - def should_suppress?(with_notification_at = nil, now = Time.now) - # - # This is the query we use. It doesn't get polled until later. - # - previous_notifications = History.all(:order => :created_at.desc, :user => self.username, :type => "notification", :event.like => '% succeeded', :fields => [:created_at]) + def should_suppress?(level, with_notification_at = nil, now = Time.now) - # - # Find the latest alert. - # - if with_notification_at.nil? - latest_notification = previous_notifications.first - latest = (latest_notification.nil? ? nil : latest_notification.created_at) - else - latest = with_notification_at - end + self.suppress_notifications_after.any? do |period, number| + # + # When testing if the next alert will suppress, we know that if only + # one alert is needed to suppress, then this function should always + # return true. + # + return true if with_notification_at and number <= 1 - return self.suppress_notifications_after.any? do |period, number| # - # If no notification time has been specified, use the earliest alert time. + # Here are the previous notifications set to this person in the last period. # - if with_notification_at.nil? or number == 0 - earliest_notification = previous_notifications[number-1] + previous_notifications = History.all( + :user => self.username, :type => "notification", + :created_at.gte => now - period, :created_at.lte => now, + :event.like => '% succeeded', + :order => :created_at.desc) + + # + # Defintely not suppressed if no notifications have been found. + # + return false if previous_notifications.count == 0 + + # + # If we're suppressed already, we need to check the time of the last alert sent + # + if @suppressed + + if with_notification_at.is_a?(Time) + latest = with_notification_at + else + latest = previous_notifications.first.created_at + end + + # + # We should not suppress this alert if the last one was sent ages ago + # + if (now - latest) >= period + return false + end + else - earliest_notification = previous_notifications[number-2] + # + # We do not suppress if we can't find a sufficient number of previous alerts + # + if previous_notifications.count < (with_notification_at.nil? ? number : number - 1) + return false + end + end - earliest = (earliest_notification.nil? ? nil : earliest_notification.created_at) + # + # If we're at the lowest level, return true now. + # + return true if !AlertGroup::LEVELS.include?(level) or AlertGroup::LEVELS.index(level) == 0 + + # + # Suppress this notification if all of the preceeding notifications were of the same or higher level. + # + return previous_notifications.alerts.all? do |a| + AlertGroup::LEVELS.index(a.level) >= AlertGroup::LEVELS.index(level) + end - (earliest.is_a?(Time) and (now - earliest) < period) or - (latest.is_a?(Time) and @suppressed and (now - latest) < period) end end @@ -236,11 +271,11 @@ module Mauve def send_alert(level, alert, now=Time.now) was_suppressed = @suppressed - @suppressed = self.should_suppress? - will_suppress = self.should_suppress?(now) + @suppressed = self.should_suppress?(level) + will_suppress = self.should_suppress?(level, now) logger.info "Starting to send notifications again for #{username}." if was_suppressed and not @suppressed - + # # We only suppress notifications if we were suppressed before we started, # and are still suppressed. -- cgit v1.2.1 From 72723a723ef7c6bf368b472c32fca3c7c397616a Mon Sep 17 00:00:00 2001 From: Patrick J Cherry Date: Thu, 16 May 2013 12:33:23 +0100 Subject: Tweaked level-based suppression condition for notifications (to work) --- lib/mauve/person.rb | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'lib') diff --git a/lib/mauve/person.rb b/lib/mauve/person.rb index eb6e28b..8ce0952 100644 --- a/lib/mauve/person.rb +++ b/lib/mauve/person.rb @@ -168,10 +168,11 @@ module Mauve return true if !AlertGroup::LEVELS.include?(level) or AlertGroup::LEVELS.index(level) == 0 # - # Suppress this notification if all of the preceeding notifications were of the same or higher level. + # Suppress this notification if all the last N of the preceeding + # notifications were of a equal or higher level. # - return previous_notifications.alerts.all? do |a| - AlertGroup::LEVELS.index(a.level) >= AlertGroup::LEVELS.index(level) + return previous_notifications.first(number).alerts.all? do |a| + AlertGroup::LEVELS.index(a.level) >= AlertGroup::LEVELS.index(level) end end -- cgit v1.2.1 From bf87bfa0e0add362febf7d376a509c68e0144d7a Mon Sep 17 00:00:00 2001 From: Patrick J Cherry Date: Thu, 16 May 2013 12:40:37 +0100 Subject: Alert level now in templates --- .../notifiers/templates/email_subject.txt.erb | 23 +--------------------- lib/mauve/notifiers/templates/sms.txt.erb | 23 +--------------------- lib/mauve/notifiers/templates/xmpp.html.erb | 6 +++--- lib/mauve/notifiers/templates/xmpp.txt.erb | 6 +++--- 4 files changed, 8 insertions(+), 50 deletions(-) mode change 100644 => 120000 lib/mauve/notifiers/templates/email_subject.txt.erb mode change 100644 => 120000 lib/mauve/notifiers/templates/sms.txt.erb (limited to 'lib') diff --git a/lib/mauve/notifiers/templates/email_subject.txt.erb b/lib/mauve/notifiers/templates/email_subject.txt.erb deleted file mode 100644 index 119c742..0000000 --- a/lib/mauve/notifiers/templates/email_subject.txt.erb +++ /dev/null @@ -1,22 +0,0 @@ -<%=alert.id %>: <%= alert.update_type.upcase %>: <% -case alert.update_type -when "cleared" -%><%= alert.cleared_at.to_s_relative %><% -when "acknowledged" -%><%= alert.acknowledged_at.to_s_relative %> by <%= alert.acknowledged_by %> until <%= alert.will_unacknowledge_at.to_s_human %><% -else -%><%= alert.raised_at.to_s_relative %><% -end -%>: <%= alert.subject %>: <%= alert.summary %><% -if alert.source != alert.subject -%> -- from <%= alert.source %><% -end -%>. <%=WebInterface.url_for(alert)%><% -if defined? was_suppressed and defined? will_suppress - if was_suppressed and not will_suppress -%> (Normal service has resumed.)<% - elsif will_suppress and not was_suppressed -%> (Further alerts suppressed until things calm down.)<% - end -end -%> diff --git a/lib/mauve/notifiers/templates/email_subject.txt.erb b/lib/mauve/notifiers/templates/email_subject.txt.erb new file mode 120000 index 0000000..802c711 --- /dev/null +++ b/lib/mauve/notifiers/templates/email_subject.txt.erb @@ -0,0 +1 @@ +xmpp.txt.erb \ No newline at end of file diff --git a/lib/mauve/notifiers/templates/sms.txt.erb b/lib/mauve/notifiers/templates/sms.txt.erb deleted file mode 100644 index faec37d..0000000 --- a/lib/mauve/notifiers/templates/sms.txt.erb +++ /dev/null @@ -1,22 +0,0 @@ -<%= alert.update_type.upcase %>: <% -case alert.update_type -when "cleared" -%><%= alert.cleared_at.to_s_relative %><% -when "acknowledged" -%><%= alert.acknowledged_at.to_s_relative %> by <%= alert.acknowledged_by %> until <%= alert.will_unacknowledge_at.to_s_human %><% -else -%><%= alert.raised_at.to_s_relative %><% -end -%>: <%= alert.subject %>: <%= alert.summary %><% -if alert.source != alert.subject -%> -- from <%= alert.source %><% -end -%>. <%=WebInterface.url_for(alert)%><% -if defined? was_suppressed and defined? will_suppress - if was_suppressed and not will_suppress -%> (Normal service has resumed.)<% - elsif will_suppress and not was_suppressed -%> (Further alerts suppressed until things calm down.)<% - end -end -%> diff --git a/lib/mauve/notifiers/templates/sms.txt.erb b/lib/mauve/notifiers/templates/sms.txt.erb new file mode 120000 index 0000000..802c711 --- /dev/null +++ b/lib/mauve/notifiers/templates/sms.txt.erb @@ -0,0 +1 @@ +xmpp.txt.erb \ No newline at end of file diff --git a/lib/mauve/notifiers/templates/xmpp.html.erb b/lib/mauve/notifiers/templates/xmpp.html.erb index 12354a2..85bec3b 100644 --- a/lib/mauve/notifiers/templates/xmpp.html.erb +++ b/lib/mauve/notifiers/templates/xmpp.html.erb @@ -1,5 +1,5 @@ -<%= alert.id%>: <%= alert.update_type.upcase %>: <% +<%= alert.id%>: <%= alert.update_type.upcase %> <%= alert.level.to_s.capitalize %>: <% case alert.update_type when "cleared" %><%= alert.cleared_at.to_s_relative %><% @@ -15,9 +15,9 @@ end %>.<% if defined? was_suppressed and defined? will_suppress if was_suppressed and not will_suppress -%>
Normal service has resumed.<% +%>
Normal service for <%= alert.level %> alerts has resumed.<% elsif will_suppress and not was_suppressed -%>
Further alerts suppressed until things calm down.<% +%>
Further <%= alert.level %> alerts suppressed until things calm down.<% end end %> diff --git a/lib/mauve/notifiers/templates/xmpp.txt.erb b/lib/mauve/notifiers/templates/xmpp.txt.erb index f63c96c..63ad000 100644 --- a/lib/mauve/notifiers/templates/xmpp.txt.erb +++ b/lib/mauve/notifiers/templates/xmpp.txt.erb @@ -1,4 +1,4 @@ -<%=alert.id %>: <%= alert.update_type.upcase %>: <% +<%=alert.id %>: <%= alert.update_type.upcase %> <%= alert.level.to_s.capitalize %>: <% case alert.update_type when "cleared" %><%= alert.cleared_at.to_s_relative %><% @@ -14,9 +14,9 @@ end %>. <%=WebInterface.url_for(alert)%><% if defined? was_suppressed and defined? will_suppress if was_suppressed and not will_suppress -%> (Normal service has resumed.)<% +%> (Normal service for <%= alert.level %> alerts has resumed.)<% elsif will_suppress and not was_suppressed -%> (Further alerts suppressed until things calm down.)<% +%> (Further <%= alert.level %> alerts suppressed until things calm down.)<% end end %> -- cgit v1.2.1 From 46e55b62412cea23beba4efb7ee169245619b6de Mon Sep 17 00:00:00 2001 From: Patrick J Cherry Date: Thu, 16 May 2013 14:13:35 +0100 Subject: Updated templates again --- lib/mauve/notifiers/templates/xmpp.html.erb | 2 +- lib/mauve/notifiers/templates/xmpp.txt.erb | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'lib') diff --git a/lib/mauve/notifiers/templates/xmpp.html.erb b/lib/mauve/notifiers/templates/xmpp.html.erb index 85bec3b..7792bd9 100644 --- a/lib/mauve/notifiers/templates/xmpp.html.erb +++ b/lib/mauve/notifiers/templates/xmpp.html.erb @@ -1,5 +1,5 @@ -<%= alert.id%>: <%= alert.update_type.upcase %> <%= alert.level.to_s.capitalize %>: <% +<%= alert.id%>: <%= alert.update_type.upcase %> (<%= alert.level %>): <% case alert.update_type when "cleared" %><%= alert.cleared_at.to_s_relative %><% diff --git a/lib/mauve/notifiers/templates/xmpp.txt.erb b/lib/mauve/notifiers/templates/xmpp.txt.erb index 63ad000..c148f41 100644 --- a/lib/mauve/notifiers/templates/xmpp.txt.erb +++ b/lib/mauve/notifiers/templates/xmpp.txt.erb @@ -1,4 +1,4 @@ -<%=alert.id %>: <%= alert.update_type.upcase %> <%= alert.level.to_s.capitalize %>: <% +<%=alert.id %>: <%= alert.update_type.upcase %> (<%= alert.level %>): <% case alert.update_type when "cleared" %><%= alert.cleared_at.to_s_relative %><% -- cgit v1.2.1 From fa7e7b8dc9d3f2333869703fc266405ee80cd5c8 Mon Sep 17 00:00:00 2001 From: Patrick J Cherry Date: Thu, 16 May 2013 14:13:45 +0100 Subject: Notification of a user now generates just one history entry, as opposed to one entry per method used. This ensures that the previous changes regarding notification suppression work for people with multiple methods of notification. --- lib/mauve/notification.rb | 4 +--- lib/mauve/person.rb | 15 +++++++++------ 2 files changed, 10 insertions(+), 9 deletions(-) (limited to 'lib') diff --git a/lib/mauve/notification.rb b/lib/mauve/notification.rb index 745660a..c164afb 100644 --- a/lib/mauve/notification.rb +++ b/lib/mauve/notification.rb @@ -319,9 +319,7 @@ module Mauve # # A bit of alert de-bouncing. # - if already_sent_to.include?(person.username) - logger.info("Already sent notification of #{alert} to #{person.username}") - else + unless already_sent_to.include?(person.username) person.send_alert(level, alert) already_sent_to << person.username end diff --git a/lib/mauve/person.rb b/lib/mauve/person.rb index 8ce0952..fd8cf98 100644 --- a/lib/mauve/person.rb +++ b/lib/mauve/person.rb @@ -253,10 +253,8 @@ module Mauve # # Log the result - note = "#{@alert.update_type.capitalize} #{name} notification to #{@person.username} (#{destination}) " + (res ? "succeeded" : "failed" ) - logger.info note+" about #{@alert}." - h = History.new(:alerts => [@alert], :type => "notification", :event => note, :user => @person.username) - h.save + # + logger.info "#{@alert.update_type.capitalize} #{name} notification to #{@person.username} (#{destination}) " + (res ? "succeeded" : "failed" ) +" about #{@alert}." return res end @@ -282,7 +280,7 @@ module Mauve # and are still suppressed. # if @suppressed or self.is_on_holiday?(now) or self.is_off_sick?(now) - note = "#{alert.update_type.capitalize} notification to #{self.username} suppressed" + note = "#{alert.update_type.capitalize} #{level} notification to #{self.username} suppressed" logger.info note + " about #{alert}." History.create(:alerts => [alert], :type => "notification", :event => note, :user => self.username) return true @@ -303,8 +301,13 @@ module Mauve :was_suppressed => was_suppressed, } ).instance_eval(&__send__(level)) end + + res = [result].flatten.any? + + note = "#{alert.update_type.capitalize} #{level} notification to #{self.username} " + (res ? "succeeded" : "failed" ) + History.create(:alerts => [alert], :type => "notification", :event => note, :user => self.username) - return [result].flatten.any? + return res end # -- cgit v1.2.1 From b27ab37aeafe7d0f4963a1c9b2e69c1d68e2bc84 Mon Sep 17 00:00:00 2001 From: Patrick J Cherry Date: Thu, 16 May 2013 14:14:41 +0100 Subject: Updated changelog --- lib/mauve/version.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib') diff --git a/lib/mauve/version.rb b/lib/mauve/version.rb index 0014105..eb3fe1f 100644 --- a/lib/mauve/version.rb +++ b/lib/mauve/version.rb @@ -5,6 +5,6 @@ module Mauve # # Current version - VERSION="3.15.6" + VERSION="3.15.11" end -- cgit v1.2.1 From ede4c121cc2ce4f91b0dc4476cadbf28a1a240b4 Mon Sep 17 00:00:00 2001 From: Patrick J Cherry Date: Tue, 21 May 2013 11:36:58 +0100 Subject: Load all alert properties when updating. --- lib/mauve/alert.rb | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'lib') diff --git a/lib/mauve/alert.rb b/lib/mauve/alert.rb index e6d1bae..24b9dae 100644 --- a/lib/mauve/alert.rb +++ b/lib/mauve/alert.rb @@ -824,7 +824,10 @@ module Mauve # alert.id = Alert.remove_html(alert.id.to_s) - alert_db = first(:alert_id => alert.id, :source => update.source) || + # + # Load the database alert, and all its properties, since we're updating. + # + alert_db = first(:alert_id => alert.id, :source => update.source, :fields => Alert.properties) || new(:alert_id => alert.id, :source => update.source) ## -- cgit v1.2.1 From 8bb164f71dc2b526e838b6ffb13c73ca641d5bbe Mon Sep 17 00:00:00 2001 From: Patrick J Cherry Date: Tue, 21 May 2013 12:23:24 +0100 Subject: Added an extra to_a to force alert lookups for the person. --- lib/mauve/person.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib') diff --git a/lib/mauve/person.rb b/lib/mauve/person.rb index fd8cf98..1158cbf 100644 --- a/lib/mauve/person.rb +++ b/lib/mauve/person.rb @@ -171,7 +171,7 @@ module Mauve # Suppress this notification if all the last N of the preceeding # notifications were of a equal or higher level. # - return previous_notifications.first(number).alerts.all? do |a| + return previous_notifications.first(number).alerts.to_a.all? do |a| AlertGroup::LEVELS.index(a.level) >= AlertGroup::LEVELS.index(level) end -- cgit v1.2.1 From 41f7d402f9cf15d49b7810dff1e0434780800328 Mon Sep 17 00:00:00 2001 From: Patrick J Cherry Date: Tue, 21 May 2013 12:27:44 +0100 Subject: Updated changelog + version --- lib/mauve/version.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib') diff --git a/lib/mauve/version.rb b/lib/mauve/version.rb index eb3fe1f..e755416 100644 --- a/lib/mauve/version.rb +++ b/lib/mauve/version.rb @@ -5,6 +5,6 @@ module Mauve # # Current version - VERSION="3.15.11" + VERSION="3.15.12" end -- cgit v1.2.1 From cdf43e9eb5a2c625bc9631d84b24965512b3559f Mon Sep 17 00:00:00 2001 From: Patrick J Cherry Date: Tue, 21 May 2013 14:32:37 +0100 Subject: Turning off global reverse dns lookups for sockets. --- lib/mauve/server.rb | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'lib') diff --git a/lib/mauve/server.rb b/lib/mauve/server.rb index bb514ce..8f8cec4 100644 --- a/lib/mauve/server.rb +++ b/lib/mauve/server.rb @@ -55,6 +55,11 @@ module Mauve # @bank_holidays = nil + # + # Turn off unwanted reverse DNS lookups across the board. + # + BasicSocket.do_not_reverse_lookup = true + # # Set up a blank config. # -- cgit v1.2.1 From 462aec120967f706b30f702ac3c997d1e2ac6c6a Mon Sep 17 00:00:00 2001 From: Patrick J Cherry Date: Tue, 21 May 2013 14:34:49 +0100 Subject: Updated changelog --- lib/mauve/version.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib') diff --git a/lib/mauve/version.rb b/lib/mauve/version.rb index e755416..d8a6aa1 100644 --- a/lib/mauve/version.rb +++ b/lib/mauve/version.rb @@ -5,6 +5,6 @@ module Mauve # # Current version - VERSION="3.15.12" + VERSION="3.15.13" end -- cgit v1.2.1 From 82dc54d6b8acbe819c6ab4fd8762d891bf415bb3 Mon Sep 17 00:00:00 2001 From: Patrick J Cherry Date: Wed, 22 May 2013 11:48:32 +0100 Subject: Update changelog + version --- lib/mauve/version.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib') diff --git a/lib/mauve/version.rb b/lib/mauve/version.rb index d8a6aa1..fa2d75a 100644 --- a/lib/mauve/version.rb +++ b/lib/mauve/version.rb @@ -5,6 +5,6 @@ module Mauve # # Current version - VERSION="3.15.13" + VERSION="3.15.14" end -- cgit v1.2.1 From 65fcea0eac21f95fd4398006551c56bc6760e261 Mon Sep 17 00:00:00 2001 From: James Hannah Date: Mon, 3 Jun 2013 15:35:29 +0100 Subject: Added an SMS provider for clockworksms.com --- lib/mauve/notifiers.rb | 1 + lib/mauve/notifiers/sms_clockwork.rb | 72 ++++++++++++++++++++++++++++++++++++ 2 files changed, 73 insertions(+) create mode 100644 lib/mauve/notifiers/sms_clockwork.rb (limited to 'lib') diff --git a/lib/mauve/notifiers.rb b/lib/mauve/notifiers.rb index 7276091..5a7acc0 100644 --- a/lib/mauve/notifiers.rb +++ b/lib/mauve/notifiers.rb @@ -1,6 +1,7 @@ require 'mauve/notifiers/email' require 'mauve/notifiers/sms_default' require 'mauve/notifiers/sms_aql' +require 'mauve/notifiers/sms_clockwork' require 'mauve/notifiers/xmpp' module Mauve diff --git a/lib/mauve/notifiers/sms_clockwork.rb b/lib/mauve/notifiers/sms_clockwork.rb new file mode 100644 index 0000000..b4bd860 --- /dev/null +++ b/lib/mauve/notifiers/sms_clockwork.rb @@ -0,0 +1,72 @@ +require 'mauve/notifiers/debug' +require 'cgi' + +module Mauve + module Notifiers + module Sms + + require 'net/https' + + class Clockwork + GATEWAY = "https://api.clockworksms.com/http/send.aspx" + + attr_writer :apikey, :from + attr_reader :name + + def initialize(name) + @name = name + end + + def send_alert(destination, alert, all_alerts, conditions = {}) + uri = URI.parse(GATEWAY) + + opts_string = { + :key => @apikey, + :to => normalize_number(destination), + :content => prepare_message(destination, alert, all_alerts, conditions), + :from => @from, + }.map { |k,v| "#{k}=#{CGI::escape(v.to_s)}" }.join("&") + + http = Net::HTTP.new(uri.host, uri.port) + if uri.port == 443 + http.use_ssl = true + http.verify_mode = OpenSSL::SSL::VERIFY_NONE + end + response, data = http.post(uri.path, opts_string, { + 'Content-Type' => 'application/x-www-form-urlencoded', + 'Content-Length' => opts_string.length.to_s + }) + + if response.kind_of?(Net::HTTPSuccess) + # + # Woo -- return true! + # + true + else + false + end + end + + protected + def prepare_message(destination, alert, all_alerts, conditions={}) + was_suppressed = conditions[:was_suppressed] || false + will_suppress = conditions[:will_suppress] || false + + template_file = File.join(File.dirname(__FILE__),"templates","sms.txt.erb") + + txt = if File.exists?(template_file) + ERB.new(File.read(template_file)).result(binding).chomp + else + logger.error("Could not find sms.txt.erb template") + alert.to_s + end + end + + def normalize_number(n) + n.split("").select { |s| (?0..?9).include?(s[0]) }.join.gsub(/^0/, "44") + end + end + end + end +end + -- cgit v1.2.1