From e140af144e987ff7f6d767f2dc48b9cf685803fd Mon Sep 17 00:00:00 2001 From: Patrick J Cherry Date: Wed, 13 Jul 2011 16:02:50 +0100 Subject: Big commit * Added manpages for all binaries * Added log-reopening for mauvealert-server, and logrotate snippet * mauveserver now adds a user on install, and runs as that user * Big logging tidy-up * Alert subjects are only overwritten by the source, when the subject in the databse is empty * Removed various attr_writer methods that were being redifined * Added a notes box to the acknowledge form, but this doesn't work yet --- lib/mauve/alert.rb | 22 +-- lib/mauve/alert_changed.rb | 10 +- lib/mauve/alert_group.rb | 12 +- lib/mauve/auth_bytemark.rb | 2 +- lib/mauve/datamapper.rb | 3 + lib/mauve/history.rb | 10 +- lib/mauve/http_server.rb | 1 + lib/mauve/mauve_thread.rb | 11 +- lib/mauve/notification.rb | 5 +- lib/mauve/notifier.rb | 5 +- lib/mauve/notifiers/email.rb | 17 +- lib/mauve/notifiers/sms_aql.rb | 5 - lib/mauve/notifiers/xmpp-smack.rb | 395 -------------------------------------- lib/mauve/notifiers/xmpp.rb | 26 +-- lib/mauve/people_list.rb | 9 +- lib/mauve/person.rb | 50 ++--- lib/mauve/processor.rb | 23 +-- lib/mauve/sender.rb | 1 - lib/mauve/server.rb | 7 +- lib/mauve/timer.rb | 6 +- lib/mauve/udp_server.rb | 8 +- lib/mauve/web_interface.rb | 23 ++- 22 files changed, 132 insertions(+), 519 deletions(-) delete mode 100644 lib/mauve/notifiers/xmpp-smack.rb (limited to 'lib/mauve') diff --git a/lib/mauve/alert.rb b/lib/mauve/alert.rb index bea2fc4..164139b 100644 --- a/lib/mauve/alert.rb +++ b/lib/mauve/alert.rb @@ -104,7 +104,7 @@ module Mauve default_scope(:default).update(:order => [:source, :importance]) def logger - Log4r::Logger.new(self.class.to_s) + @logger ||= self.class.logger end def time_relative(secs) @@ -186,7 +186,7 @@ module Mauve if @changes_before_save.has_key?(:update_type) or (self.update_type == "raised" and is_a_change) self.notify - h = History.new(:alert => self, :type => "update") + h = History.new(:alert_id => self.id, :type => "update") if self.update_type == "acknowledged" h.event = "ACKNOWLEDGED by #{self.acknowledged_by} until #{self.will_unacknowledge_at}" @@ -200,7 +200,9 @@ module Mauve end - h.save + if !h.save + logger.error "Unable to save history due to #{h.errors.inspect}" + end end true @@ -244,7 +246,6 @@ module Mauve # 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" - logger.debug("saving #{self.inspect}") logger.error("Couldn't save #{self}") unless save end @@ -384,8 +385,6 @@ module Mauve time_offset = (reception_time - transmission_time).round - logger.debug("Update received from a host #{time_offset}s behind") if time_offset.abs > 5 - # # Make sure there is no HTML in the update source. # @@ -457,13 +456,14 @@ module Mauve # # Set the subject # - if alert.subject and !alert.subject.empty? + if alert.subject and !alert.subject.empty? alert_db.subject = Alert.remove_html(alert.subject) - else + + elsif alert_db.subject.nil? # # Use the source, Luke, but only when the subject hasn't already been set. # - alert_db.subject = alert_db.source if alert_db.subject.nil? + alert_db.subject = alert_db.source end alert_db.summary = Alert.remove_html(alert.summary) if alert.summary && !alert.summary.empty? @@ -501,7 +501,7 @@ module Mauve # if update.replace alert_ids_mentioned = update.alert.map { |alert| alert.id } - logger.debug "Replacing all alerts from #{update.source} except "+alert_ids_mentioned.join(",") + logger.info "Replacing all alerts from #{update.source} except "+alert_ids_mentioned.join(",") all(:source => update.source, :alert_id.not => alert_ids_mentioned, :cleared_at => nil @@ -513,7 +513,7 @@ module Mauve end def logger - Log4r::Logger.new("Mauve::Alert") + Log4r::Logger.new(self.to_s) end end end diff --git a/lib/mauve/alert_changed.rb b/lib/mauve/alert_changed.rb index 0b0f72a..740b9dc 100644 --- a/lib/mauve/alert_changed.rb +++ b/lib/mauve/alert_changed.rb @@ -39,7 +39,7 @@ module Mauve ) if old_changed if !old_changed.update(:remind_at => nil) - logger.error "Couldn't save #{old_changed}, will get duplicate reminders" + logger.info "Couldn't save #{old_changed}, will get duplicate reminders" end end end @@ -74,7 +74,7 @@ module Mauve previous.was_relevant_when_raised? else # a bug, but hardly inconceivable :) - logger.warn("Could not see that #{alert} was raised with #{person} "+ + logger.info("Could not see that #{alert} was raised with #{person} "+ "but further updates exist (e.g. #{self}) "+ "- you may see spurious notifications as a result") true @@ -86,18 +86,18 @@ module Mauve # def remind unless alert.is_a?(Alert) - logger.debug "#{self.inspect} lost alert #{alert_id}. Killing self." + logger.info "#{self.inspect} lost alert #{alert_id}. Killing self." destroy! return false end - logger.debug "Reminding someone about #{self.inspect}" + logger.info "Reminding someone about #{self.inspect}" alert_group = AlertGroup.matches(alert)[0] if !alert_group || alert.acknowledged? - logger.debug((alert_group ? + logger.info((alert_group ? "Alert already acknowledged" : "No alert group matches any more" ) + ", no reminder due" diff --git a/lib/mauve/alert_group.rb b/lib/mauve/alert_group.rb index 75f97fd..bfdb3cf 100644 --- a/lib/mauve/alert_group.rb +++ b/lib/mauve/alert_group.rb @@ -40,17 +40,15 @@ module Mauve # Make sure we've got a matching group # if groups.empty? - logger.warn "no groups found for #{alert}" + logger.warn "no groups found for #{alert}!" next end # - # Notify just the group that thinks this alert is the most urgent. + # Notify just the first group # - logger.warn "Found #{groups.length} matching groups for #{alert}" if groups.length > 1 - this_group = groups.first - logger.info("notifying group #{this_group} of #{alert} (matching #{this_group.level})") + logger.info("notifying group #{this_group} of #{alert}") this_group.notify(alert) end end @@ -103,7 +101,7 @@ module Mauve def matches_alert?(alert) unless alert.is_a?(Alert) - logger.warn "Got given a #{alert.class} instead of an Alert!" + logger.error "Got given a #{alert.class} instead of an Alert!" logger.debug caller.join("\n") return false end @@ -126,7 +124,7 @@ module Mauve # If there are no notifications defined. # if notifications.nil? - logger.warn("No notifications found for #{alert}") + logger.warn("No notifications found for #{self.inspect}") return end diff --git a/lib/mauve/auth_bytemark.rb b/lib/mauve/auth_bytemark.rb index 2273c36..c0834e0 100644 --- a/lib/mauve/auth_bytemark.rb +++ b/lib/mauve/auth_bytemark.rb @@ -46,7 +46,7 @@ class AuthBytemark Mauve::Server.instance.logger.warn "Fault code is #{fault.faultCode} stating #{fault.faultString}" return false rescue Exception => ex - Mauve::Server.instance.logger.warn "Caught #{ex.to_s} whilst trying to loging for #{login}" + Mauve::Server.instance.logger.error "Caught #{ex.to_s} whilst trying to loging for #{login}" Mauve::Server.instance.logger.debug ex.backtrace.join("\n") return false end diff --git a/lib/mauve/datamapper.rb b/lib/mauve/datamapper.rb index 27d89a3..f46536e 100644 --- a/lib/mauve/datamapper.rb +++ b/lib/mauve/datamapper.rb @@ -11,3 +11,6 @@ require 'dm-migrations' require 'dm-validations' require 'dm-timestamps' + +# DataMapper::Model.raise_on_save_failure = true + diff --git a/lib/mauve/history.rb b/lib/mauve/history.rb index 6c4969b..1c2cdf4 100644 --- a/lib/mauve/history.rb +++ b/lib/mauve/history.rb @@ -12,10 +12,16 @@ module Mauve property :id, Serial property :alert_id, Integer, :required => true property :type, String, :required => true, :default => "unknown" - property :event, Text, :required => true - property :created_at, DateTime + property :event, Text, :required => true, :default => "Nothing set" + property :created_at, DateTime, :required => true belongs_to :alert + + before :valid?, :set_created_at + + def set_created_at(context = :default) + self.created_at = Time.now unless self.created_at.is_a?(Time) or self.created_at.is_a?(DateTime) + end def logger Log4r::Logger.new self.class.to_s diff --git a/lib/mauve/http_server.rb b/lib/mauve/http_server.rb index 21c89e5..cb705ea 100644 --- a/lib/mauve/http_server.rb +++ b/lib/mauve/http_server.rb @@ -87,6 +87,7 @@ module Mauve attr_accessor :session_secret def initialize + super @port = 1288 @ip = "127.0.0.1" @document_root = "/usr/share/mauvealert" diff --git a/lib/mauve/mauve_thread.rb b/lib/mauve/mauve_thread.rb index 79e742a..1aa8619 100644 --- a/lib/mauve/mauve_thread.rb +++ b/lib/mauve/mauve_thread.rb @@ -6,6 +6,7 @@ module Mauve class MauveThread def initialize + @thread = nil end def logger @@ -58,7 +59,7 @@ module Mauve end def frozen? - @frozen and @thread.stop? + defined? @frozen and @frozen and @thread.stop? end def thaw @@ -86,6 +87,10 @@ module Mauve @thread.is_a?(Thread) and @thread.alive? end + def stop? + @thread.is_a?(Thread) and @thread.stop? + end + def join(ok_exceptions=[]) @thread.join if @thread.is_a?(Thread) end @@ -94,6 +99,10 @@ module Mauve @thread.raise(ex) end + def backtrace + @thread.backtrace if @thread.is_a?(Thread) + end + def restart self.stop self.start diff --git a/lib/mauve/notification.rb b/lib/mauve/notification.rb index 2f77a13..ed96f7e 100644 --- a/lib/mauve/notification.rb +++ b/lib/mauve/notification.rb @@ -44,10 +44,7 @@ module Mauve plus_one_week = MauveTime.now + 604800 # ish while offset < plus_one_week offset += interval - if DuringRunner.new(offset, @alert, &@during).now? - @logger.debug("Found reminder time of #{offset}") - return offset - end + return offset if DuringRunner.new(offset, @alert, &@during).now? end @logger.info("Could not find a reminder time less than a week "+ "for #{@alert}.") diff --git a/lib/mauve/notifier.rb b/lib/mauve/notifier.rb index 90df895..e62f7f4 100644 --- a/lib/mauve/notifier.rb +++ b/lib/mauve/notifier.rb @@ -13,6 +13,7 @@ module Mauve attr_accessor :sleep_interval def initialize + super end def main_loop @@ -22,9 +23,7 @@ module Mauve sz = Server.notification_buffer_size return if sz == 0 - - logger.debug("Notifier buffer is #{sz} in length") - + my_threads = [] sz.times do person, *args = Server.notification_pop diff --git a/lib/mauve/notifiers/email.rb b/lib/mauve/notifiers/email.rb index 129afec..77b10f1 100644 --- a/lib/mauve/notifiers/email.rb +++ b/lib/mauve/notifiers/email.rb @@ -7,17 +7,9 @@ module Mauve module Notifiers module Email - - class Default + class Default attr_reader :name - attr :server, true - attr :port, true - attr :username, true - attr :password, true - attr :login_method, true - attr :from, true - attr :subject_prefix, true - attr :email_suffix, true + attr_writer :server, :port, :password, :login_method, :from, :subject_prefix, :email_suffix def username=(username) @login_method ||= :plain @@ -47,20 +39,15 @@ module Mauve message = prepare_message(destination, alert, all_alerts, conditions) args = [@server, @port] args += [@username, @password, @login_method.to_sym] if @login_method - history = Mauve::History.new(:alert => alert, :type => :notification) begin Net::SMTP.start(*args) do |smtp| smtp.send_message(message, @from, destination) end - history.event = "Sent mail to #{destination}." - history.save true rescue StandardError => ex logger.error "SMTP failure: #{ex.to_s}" logger.debug ex.backtrace.join("\n") - history.event = "Failed to send mail to #{destination} due to #{ex.to_s}" - history.save false end end diff --git a/lib/mauve/notifiers/sms_aql.rb b/lib/mauve/notifiers/sms_aql.rb index b295e6c..dbda229 100644 --- a/lib/mauve/notifiers/sms_aql.rb +++ b/lib/mauve/notifiers/sms_aql.rb @@ -41,17 +41,12 @@ module Mauve 'Content-Length' => opts_string.length.to_s }) - history = Mauve::History.new(:alert => alert, :type => :notification) if response.kind_of?(Net::HTTPSuccess) - history.event = "Sent SMS via AQL to #{destination}" - history.save # # Woo -- return true! # true else - history.event = "Failed to send SMS via AQL to #{destination} due to #{response.class.to_s}" - history.save false end end diff --git a/lib/mauve/notifiers/xmpp-smack.rb b/lib/mauve/notifiers/xmpp-smack.rb deleted file mode 100644 index a160a35..0000000 --- a/lib/mauve/notifiers/xmpp-smack.rb +++ /dev/null @@ -1,395 +0,0 @@ -# encoding: utf-8 - -# Ruby. -require 'pp' -require 'log4r' -require 'monitor' - -# Java. Note that paths are mangeled in jmauve_starter. -require 'java' -require 'smack.jar' -require 'smackx.jar' -include_class "org.jivesoftware.smack.XMPPConnection" -include_class "org.jivesoftware.smackx.muc.MultiUserChat" -include_class "org.jivesoftware.smack.RosterListener" - -module Mauve - - module Notifiers - - module Xmpp - - class XMPPSmackException < StandardError - end - - ## Main wrapper to smack java library. - # - # @author Yann Golanski - # @see http://www.igniterealtime.org/builds/smack/docs/3.1.0/javadoc/ - # - # This is a singleton which is not idea but works well for mauve's - # configuration file set up. - # - # In general, this class is meant to be intialized then the method - # create_slave_thread must be called. The latter will spawn a new - # thread that will do the connecting and sending of messages to - # the XMPP server. Once this is done, messages can be send via the - # send_msg() method. Those will be queued and depending on the load, - # should be send quickly enough. This is done so that the main thread - # can not worry about sending messages and can do important work. - # - # @example - # bot = Mauve::Notifiers::Xmpp::XMPPSmack.new() - # bot.run_slave_thread("chat.bytemark.co.uk", 'mauvealert', 'TopSecret') - # msg = "What fresh hell is this? -- Dorothy Parker." - # bot.send_msg("yann@chat.bytemark.co.uk", msg) - # bot.send_msg("muc:test@conference.chat.bytemark.co.uk", msg) - # - # @FIXME This won't quiet work with how mauve is set up. - # - class XMPPSmack - - # Globals are evil. - @@instance = nil - - # Default constructor. - # - # A queue (@queue) is used to pass information between master/slave. - def initialize () - extend(MonitorMixin) - @logger = Log4r::Logger.new "mauve::XMPP_smack<#{Process.pid}>" - @queue = Queue.new - @xmpp = nil - @name = "mauve alert" - @slave_thread = nil - @regexp_muc = Regexp.compile(/^muc\:/) - @regexp_tail = Regexp.compile(/\/.*$/) - @jid_created_chat = Hash.new() - @separator = '<->' - @logger.info("Created XMPPSmack singleton") - end - - # Returns the instance of the XMPPSmack singleton. - # - # @param [String] login The JID as a full address. - # @param [String] pwd The password corresponding to the JID. - # @return [XMPPSmack] The singleton instance. - def self.instance (login, pwd) - if true == @@instance.nil? - @@instance = XMPPSmack.new - jid, tmp = login.split(/@/) - srv, name = tmp.split(/\//) - name = "Mauve Alert Bot" if true == name.nil? - @@instance.run_slave_thread(srv, jid, pwd, name) - sleep 5 # FIXME: This really should be synced... But how? - end - return @@instance - end - - # Create the thread that sends messages to the server. - # - # @param [String] srv The server address. - # @param [String] jid The JID. - # @param [String] pwd The password corresponding to the JID. - # @param [String] name The bot name. - # @return [NULL] nada - def run_slave_thread (srv, jid, pwd, name) - @srv = srv - @jid = jid - @pwd = pwd - @name = name - @logger.info("Creating slave thread on #{@jid}@#{@srv}/#{@name}.") - @slave_thread = Thread.new do - self.create_slave_thread() - end - return nil - end - - # Returns whether instance is connected and authenticated. - # - # @return [Boolean] True or false. - def is_connected_and_authenticated? () - return false if true == @xmpp.nil? - return (@xmpp.isConnected() and @xmpp.isAuthenticated()) - end - - # Creates the thread that does the actual sending to XMPP. - # @return [NULL] nada - def create_slave_thread () - begin - @logger.info("Slave thread is now alive.") - self.open() - loop do - rcp, msg = @queue.deq().split(@separator, 2) - @logger.debug("New message for '#{rcp}' saying '#{msg}'.") - if rcp.match(@regexp_muc) - room = rcp.gsub(@regexp_muc, '').gsub(@regexp_tail, '') - self.send_to_muc(room, msg) - else - self.send_to_jid(rcp, msg) - end - end - rescue XMPPSmackException - @logger.fatal("Something is wrong") - ensure - @logger.info("XMPP bot disconnect.") - @xmpp.disconnect() - end - return nil - end - - # Send a message to the recipient. - # - # @param [String] rcp The recipent MUC or JID. - # @param [String] msg The message. - # @return [NULL] nada - def send_msg(rcp, msg) - #if @slave_thread.nil? or not self.is_connected_and_authenticated?() - # str = "There is either no slave thread running or a disconnect..." - # @logger.warn(str) - # self.reconnect() - #end - @queue.enq(rcp + @separator + msg) - return nil - end - - # Sends a message to a room. - # - # @param [String] room The name of the room. - # @param [String] mgs The message to send. - # @return [NULL] nada - def send_to_muc (room, msg) - if not @jid_created_chat.has_key?(room) - @jid_created_chat[room] = MultiUserChat.new(@xmpp, room) - @jid_created_chat[room].join(@name) - end - @logger.debug("Sending to MUC '#{room}' message '#{msg}'.") - @jid_created_chat[room].sendMessage(msg) - return nil - end - - # Sends a message to a jid. - # - # Do not destroy the chat, we can reuse it when the user log back in again. - # Maybe? - # - # @param [String] jid The JID of the recipient. - # @param [String] mgs The message to send. - # @return [NULL] nada - def send_to_jid (jid, msg) - if true == jid_is_available?(jid) - if not @jid_created_chat.has_key?(jid) - @jid_created_chat[jid] = @xmpp.getChatManager.createChat(jid, nil) - end - @logger.debug("Sending to JID '#{jid}' message '#{msg}'.") - @jid_created_chat[jid].sendMessage(msg) - end - return nil - end - - # Check to see if the jid is available or not. - # - # @param [String] jid The JID of the recipient. - # @return [Boolean] Whether we can send a message or not. - def jid_is_available?(jid) - if true == @xmpp.getRoster().getPresence(jid).isAvailable() - @logger.debug("#{jid} is available. Status is " + - "#{@xmpp.getRoster().getPresence(jid).getStatus()}") - return true - else - @logger.warn("#{jid} is not available. Status is " + - "#{@xmpp.getRoster().getPresence(jid).getStatus()}") - return false - end - end - - # Opens a connection to the xmpp server at given port. - # - # @return [NULL] nada - def open() - @logger.info("XMPP bot is being created.") - self.open_connection() - self.open_authentication() - self.create_roster() - sleep 5 - return nil - end - - # Connect to server. - # - # @return [NULL] nada - def open_connection() - @xmpp = XMPPConnection.new(@srv) - if false == self.connect() - str = "Connection refused" - @logger.error(str) - raise XMPPSmackException.new(str) - end - @logger.debug("XMPP bot connected successfully.") - return nil - end - - # Authenticat connection. - # - # @return [NULL] nada - def open_authentication() - if false == self.login(@jid, @pwd) - str = "Authentication failed" - @logger.error(str) - raise XMPPSmackException.new(str) - end - @logger.debug("XMPP bot authenticated successfully.") - return nil - end - - # Create a new roster and listener. - # - # @return [NULL] nada - def create_roster - @xmpp.getRoster().addRosterListener(RosterListener.new()) - @xmpp.getRoster().reload() - @xmpp.getRoster().getPresence(@xmpp.getUser).setStatus( - "Purple alert! Purple alert!") - @logger.debug("XMPP bot roster aquired successfully.") - return nil - end - - # Connects to the server. - # - # @return [Boolean] true (aka sucess) or false (aka failure). - def connect () - @xmpp.connect() - return @xmpp.isConnected() - end - - # Login onto the server. - # - # @param [String] jid The JID. - # @param [String] pwd The password corresponding to the JID. - # @return [Boolean] true (aka sucess) or false (aka failure). - def login (jid, pwd) - @xmpp.login(jid, pwd, @name) - return @xmpp.isAuthenticated() - end - - # Reconnects in case of errors. - # - # @return [NULL] nada - def reconnect() - @xmpp.disconnect - @slave_thread = Thread.new do - self.create_slave_thread() - end - return nil - end - - def presenceChanged () - end - - end # XMPPSmack - - - ## This is the class that gets called in person.rb. - # - # This class is a wrapper to XMPPSmack which does the hard work. It is - # done this way to conform to the mauve configuration file way of - # defining notifications. - # - # @author Yann Golanski - class Default - - # Name of the class. - attr_reader :name - - # Atrtribute. - attr_accessor :jid - - # Atrtribute. - attr_accessor :password - - # Atrtribute. - attr_accessor :initial_jid - - # Atrtribute. - attr_accessor :initial_messages - - # Default constructor. - # - # @param [String] name The name of the notifier. - def initialize (name) - extend(MonitorMixin) - @name = name - @logger = Log4r::Logger.new "mauve::XMPP_default<#{Process.pid}>" - end - - # Sends a message to the relevant jid or muc. - # - # We have no way to know if a messages was recieved, only that - # we send it. - # - # @param [String] destionation - # @param [Alert] alert A mauve alert class - # @param [Array] all_alerts subset of current alerts - # @param [Hash] conditions Supported conditions, see above. - # @return [Boolean] Whether a message can be send or not. - def send_alert(destination, alert, all_alerts, conditions = nil) - synchronize { - client = XMPPSmack.instance(@jid, @password) - if not destination.match(/^muc:/) - if false == client.jid_is_available?(destination.gsub(/^muc:/, '')) - return false - end - end - client.send_msg(destination, convert_alert_to_message(alert)) - return true - } - end - - # Takes an alert and converts it into a message. - # - # @param [Alert] alert The alert to convert. - # @return [String] The message, either as HTML. - def convert_alert_to_message(alert) - arr = alert.summary_three_lines - str = arr[0] + ": " + arr[1] - str += " -- " + arr[2] if false == arr[2].nil? - str += "." - return str - #return alert.summary_two_lines.join(" -- ") - #return "

" + alert.summary_two_lines.join("
") + "

" - end - - # This is so unit tests can run fine. - include Debug - - end # Default - - end - end -end - -# This is a simple example of usage. Run with: -# ../../../jmauve_starter.rb xmpp-smack.rb -# Clearly, the mauve jabber password is not correct. -# -# /!\ WARNING: DO NOT COMMIT THE REAL PASSWORD TO MERCURIAL!!! -# -def send_msg() - bot = Mauve::Notifiers::Xmpp::XMPPSmack.instance( - "mauvealert@chat.bytemark.co.uk/testing1234", '') - msg = "What fresh hell is this? -- Dorothy Parker." - bot.send_msg("yann@chat.bytemark.co.uk", msg) - bot.send_msg("muc:test@conference.chat.bytemark.co.uk", msg) - sleep 2 -end - -if __FILE__ == './'+$0 - Thread.abort_on_exception = true - logger = Log4r::Logger.new('mauve') - logger.level = Log4r::DEBUG - logger.add Log4r::Outputter.stdout - send_msg() - send_msg() - logger.info("START") - logger.info("END") -end diff --git a/lib/mauve/notifiers/xmpp.rb b/lib/mauve/notifiers/xmpp.rb index c4e1785..8131096 100644 --- a/lib/mauve/notifiers/xmpp.rb +++ b/lib/mauve/notifiers/xmpp.rb @@ -66,10 +66,10 @@ module Mauve include Jabber # Atrtribute. - attr_reader :name + attr_reader :name, :jid # Atrtribute. - attr_accessor :jid, :password + attr_accessor :password def initialize(name) Jabber::logger = self.logger @@ -80,7 +80,7 @@ module Mauve @mucs = {} @roster = nil @closing = false - + @client = nil end def logger @@ -93,7 +93,7 @@ module Mauve end def connect - logger.info "Jabber starting connection to #{@jid}" + logger.debug "Starting connection to #{@jid}" # Make sure we're disconnected. self.close if @client.is_a?(Client) @@ -110,7 +110,6 @@ module Mauve # already @roster.add_subscription_request_callback do |ri, presence| Thread.new do - logger.debug "Known? #{is_known_contact?(presence.from).inspect}" if is_known_contact?(presence.from) logger.info("Accepting subscription request from #{presence.from}") @roster.accept_subscription(presence.from) @@ -127,10 +126,11 @@ module Mauve end @roster.wait_for_roster - logger.debug "Jabber authenticated, setting presence" @client.send(Presence.new(nil, "Woo!").set_type(nil)) + logger.info "Connected as #{@jid}" + @client.on_exception do |ex, stream, where| # # The XMPP4R exception clauses in Stream all close the stream, so @@ -203,17 +203,7 @@ module Mauve alert.to_s end - history = Mauve::History.new(:alert_id => alert.id, :type => :notification) - - if send_message(destination_jid, txt) - history.event = "Sent XMPP message to #{destination_jid}" - history.save - true - else - history.event = "Failed to send XMPP message to #{destination_jid}" - history.save - false - end + send_message(destination_jid, txt) end # Sends a message to the destionation. @@ -297,12 +287,12 @@ module Mauve end if !@mucs[jid.strip].active? - logger.info("Joining #{jid}") # # Make sure we have a resource. # @mucs[jid.strip].join(jid, password) + logger.info("Joined #{jid}") else logger.debug("Already joined #{jid}.") end diff --git a/lib/mauve/people_list.rb b/lib/mauve/people_list.rb index 23e0c1e..32e0708 100644 --- a/lib/mauve/people_list.rb +++ b/lib/mauve/people_list.rb @@ -34,11 +34,16 @@ module Mauve # Return the array of people # def people - logger.warn "No-one found in the people list for #{self.label}" if self.list.empty? - list.collect do |name| + l = list.collect do |name| Configuration.current.people.has_key?(name) ? Configuration.current.people[name] : nil end.reject{|person| person.nil?} + # + # Hmm.. no-one in the list?! + # + logger.warn "No-one found in the people list for #{self.label}" if l.empty? + + l end end diff --git a/lib/mauve/person.rb b/lib/mauve/person.rb index 0290faf..cf29ff9 100644 --- a/lib/mauve/person.rb +++ b/lib/mauve/person.rb @@ -63,9 +63,13 @@ module Mauve # and turn them into false. # res = notification_method.send_alert(destination, @alert, @other_alerts, conditions) + # # Log the result - logger.debug "Notification " + (res ? "succeeded" : "failed" ) + " for #{@person.username} using notifier '#{name}' to '#{destination}'" + note = "#{@alert.update_type.upcase}: notification " + (res ? "succeeded" : "failed" ) + " for #{@person.username} using notifier '#{name}' to '#{destination}'." + logger.info note + h = History.new(:alert_id => @alert.id, :type => "notification", :event => note) + logger.error "Unable to save history due to #{h.errors.inspect}" if !h.save res end @@ -144,7 +148,6 @@ module Mauve end def remind(alert, level) - logger.debug("Reminder for #{alert} send at level #{level}.") send_alert(level, alert) end @@ -153,45 +156,45 @@ module Mauve # def send_alert(level, alert) now = MauveTime.now - suppressed_changed = nil + threshold_breached = @notification_thresholds.any? do |period, previous_alert_times| first = previous_alert_times.first first.is_a?(MauveTime) and (now - first) < period end - this_alert_suppressed = false + was_suppressed = self.suppressed? if Server.instance.started_at > alert.updated_at.to_time and (Server.instance.started_at + Server.instance.initial_sleep) > MauveTime.now - logger.warn("Alert last updated in prior run of mauve -- ignoring for initial sleep period.") - this_alert_suppressed = true - elsif threshold_breached - unless suppressed? - logger.warn("Suspending notifications to #{username} until further notice.") - suppressed_changed = true - end + logger.info("Alert last updated in prior run of mauve -- ignoring for initial sleep period.") + return + end + + if threshold_breached + logger.info("Suspending notifications to #{username} until further notice.") unless was_suppressed @suppressed = true + else - if suppressed? - suppressed_changed = false - logger.warn "Starting to send notifications again for #{username}." - else - logger.info "Notifying #{username} of #{alert} at level #{level}" - end + logger.info "Starting to send notifications again for #{username}." if was_suppressed @suppressed = false + end - return if suppressed? or this_alert_suppressed + # + # We only suppress notifications if we were suppressed before we started, + # and are still suppressed. + # + return if was_suppressed and self.suppressed? - Server.notification_push([self, level, alert, suppressed_changed]) + Server.notification_push([self, level, alert, was_suppressed]) end - def do_send_alert(level, alert, suppressed_changed) + def do_send_alert(level, alert, was_suppressed) result = NotificationCaller.new( self, alert, current_alerts, Configuration.current.notification_methods, - :suppressed_changed => suppressed_changed + :was_suppressed => was_suppressed ).instance_eval(&__send__(level)) if result @@ -205,10 +208,9 @@ module Mauve @notification_thresholds[period].push MauveTime.now @notification_thresholds[period].shift end - - logger.info("Notification for #{username} of #{alert} at level #{level} has been successful") + true else - logger.error("Failed to notify #{username} about #{alert} at level #{level}") + false end end diff --git a/lib/mauve/processor.rb b/lib/mauve/processor.rb index 083b9a1..f36dacb 100644 --- a/lib/mauve/processor.rb +++ b/lib/mauve/processor.rb @@ -11,9 +11,7 @@ module Mauve attr_accessor :transmission_cache_expire_time, :sleep_interval def initialize - # Set the logger up - @logger = Log4r::Logger.new(self.class.to_s) - + super # # Set up the transmission id cache # @@ -22,10 +20,11 @@ module Mauve @transmission_cache_checked_at = Time.now end - def main_loop - - logger.info("Buffer has packets waiting...") if Server.packet_buffer_size > 0 + def logger + @logger ||= Log4r::Logger.new(self.class.to_s) + end + def main_loop # # Only do the loop a maximum of 10 times every @sleep_interval seconds # @@ -39,7 +38,9 @@ module Mauve Timer.instance.freeze unless Timer.instance.frozen? - @logger.debug("Got #{data.inspect} from #{client.inspect}") + raise ArgumentError, "arse" + + logger.debug("Got #{data.inspect} from #{client.inspect}") ip_source = "#{client[3]}:#{client[1]}" update = Proto::AlertUpdate.new @@ -48,14 +49,14 @@ module Mauve update.parse_from_string(data) if @transmission_id_cache[update.transmission_id.to_s] - @logger.debug("Ignoring duplicate transmission id #{update.transmission_id}") + logger.info("Ignoring duplicate transmission id #{update.transmission_id}") # # Continue with next packet. # next end - @logger.debug "Update #{update.transmission_id} sent at #{update.transmission_time} from "+ + logger.info "Update #{update.transmission_id} sent at #{update.transmission_time} from "+ "'#{update.source}'@#{ip_source} alerts #{update.alert.length}" Alert.receive_update(update, received_at) @@ -64,10 +65,10 @@ module Mauve NotImplementedError, DataObjects::IntegrityError => ex - @logger.error "#{ex} (#{ex.class}) while parsing #{data.length} bytes "+ + logger.error "#{ex} (#{ex.class}) while parsing #{data.length} bytes "+ "starting '#{data[0..15].inspect}' from #{ip_source}" - @logger.debug ex.backtrace.join("\n") + logger.debug ex.backtrace.join("\n") ensure @transmission_id_cache[update.transmission_id.to_s] = MauveTime.now diff --git a/lib/mauve/sender.rb b/lib/mauve/sender.rb index 122456c..ad047fe 100644 --- a/lib/mauve/sender.rb +++ b/lib/mauve/sender.rb @@ -3,7 +3,6 @@ require 'ipaddr' require 'resolv' require 'socket' require 'mauve/mauve_time' -require 'pp' module Mauve class Sender diff --git a/lib/mauve/server.rb b/lib/mauve/server.rb index 51587c0..4bd5a0f 100644 --- a/lib/mauve/server.rb +++ b/lib/mauve/server.rb @@ -43,7 +43,7 @@ module Mauve # Sleep time between pooling the @buffer buffer. @sleep = 1 - @freeze = false + @frozen = false @stop = false @stopped_at = MauveTime.now @@ -166,7 +166,7 @@ module Mauve begin klass.instance.join rescue StandardError => ex - logger.warn "Caught #{ex.to_s} whilst checking #{klass} thread" + logger.error "Caught #{ex.to_s} whilst checking #{klass} thread" logger.debug ex.backtrace.join("\n") end @@ -177,7 +177,8 @@ module Mauve end # - # Now do the same with other threads. + # Now do the same with other threads. However if these ones crash, the + # server has to stop, as there is no method to restart them. # thread_list.each do |t| diff --git a/lib/mauve/timer.rb b/lib/mauve/timer.rb index 40abe43..f6ada88 100644 --- a/lib/mauve/timer.rb +++ b/lib/mauve/timer.rb @@ -14,6 +14,7 @@ module Mauve attr_accessor :sleep_interval, :last_run_at def initialize + super @initial_sleep = 300 @initial_sleep_threshold = 300 end @@ -29,7 +30,6 @@ module Mauve # look for the next alert_changed object. # if next_alert.nil? or next_alert.due_at > MauveTime.now - logger.debug("Next alert was #{next_alert} due at #{next_alert.due_at}") unless next_alert.nil? next_alert_changed = AlertChanged.find_next_with_event end @@ -51,12 +51,12 @@ module Mauve # # Sleep indefinitely # - logger.debug("Nothing to notify about -- snoozing indefinitely.") + logger.info("Nothing to notify about -- snoozing indefinitely.") else # # La la la nothing to do. # - logger.debug("Next to notify: #{next_to_notify} -- snoozing until #{next_to_notify.due_at}") + logger.info("Next to notify: #{next_to_notify} -- snoozing until #{next_to_notify.due_at}") end # diff --git a/lib/mauve/udp_server.rb b/lib/mauve/udp_server.rb index 59bc5bc..8649efe 100644 --- a/lib/mauve/udp_server.rb +++ b/lib/mauve/udp_server.rb @@ -15,6 +15,7 @@ module Mauve attr_accessor :ip, :port, :sleep_interval def initialize + super # # Set the logger up # @@ -49,7 +50,7 @@ module Mauve @socket.bind(@ip, @port) - logger.debug("Successfully opened UDP socket on #{@ip}:#{@port}") + logger.info("Successfully opened UDP socket on #{@ip}:#{@port}") end def close_socket @@ -59,10 +60,11 @@ module Mauve @socket.close rescue IOError => ex # Just in case there is some sort of explosion! - logger.debug("Caught IOError #{ex.to_s}") + logger.error "Caught IOError #{ex.to_s}" + logger.debug ex.backtrace.join("\n") end - logger.debug("Successfully closed UDP socket") + logger.info("Successfully closed UDP socket") end def main_loop diff --git a/lib/mauve/web_interface.rb b/lib/mauve/web_interface.rb index 3770924..4594e10 100644 --- a/lib/mauve/web_interface.rb +++ b/lib/mauve/web_interface.rb @@ -185,6 +185,7 @@ EOF n_hours = params[:n_hours] || 2 type_hours = params[:type_hours] || "daylight" alerts = params[:alerts] || [] + note = params[:note] || nil n_hours = (n_hours.to_i > 188 ? 188 : n_hours.to_i) @@ -196,18 +197,28 @@ EOF succeeded = [] failed = [] - + alerts.each do |k,v| begin a = Alert.get!(k.to_i) rescue DataMapper::ObjectNotFoundError => ex failed << ex + next end + logger.debug "arse" + begin a.acknowledge!(@person, ack_until) + logger.debug note + unless note.to_s.empty? + h = History.new(:alert_id => a.id, :type => "note", :event => note.to_s) + logger.debug h.errors unless h.save + end succeeded << a rescue StandardError => ex + logger.error "Caught #{ex.to_s} when trying to save #{a.inspect}" + logger.debug ex.backtrace.join("\n") failed << ex end end @@ -454,14 +465,15 @@ EOF result = begin auth.authenticate(usr,pwd) rescue Exception => ex - @logger.debug "Caught exception during Bytemark auth for #{usr} (#{ex.to_s})" + logger.error "Caught exception during Bytemark auth for #{usr} (#{ex.to_s})" + logger.debug ex.backtrace.join("\n") false end if true == result return true else - @logger.debug "Bytemark authentication failed for #{usr}" + logger.warn "Bytemark authentication failed for #{usr}" end # @@ -472,14 +484,15 @@ EOF Digest::SHA1.hexdigest(params['password']) == Configuration.current.people[usr].password end rescue Exception => ex - @logger.debug "Caught exception during local auth for #{usr} (#{ex.to_s})" + logger.error "Caught exception during local auth for #{usr} (#{ex.to_s})" + logger.debug ex.backtrace.join("\n") false end if true == result return true else - @logger.debug "Local authentication failed for #{usr}" + logger.warn "Local authentication failed for #{usr}" end # -- cgit v1.2.1