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 --- .hgignore | 1 + Makefile | 8 +- bin/mauveclient | 4 + bin/mauveconsole | 65 +++++- bin/mauveserver | 96 +++++++-- debian/mauvealert-server.init | 22 ++- debian/mauvealert-server.logrotate | 10 + debian/mauvealert-server.postinst | 20 ++ debian/mauvealert-server.postrm | 23 +++ 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 ++- mauveserver.conf | 58 +++--- views/_acknowledge_input.haml | 5 +- views/alert.haml | 6 +- 34 files changed, 386 insertions(+), 583 deletions(-) create mode 100644 debian/mauvealert-server.logrotate create mode 100644 debian/mauvealert-server.postinst create mode 100644 debian/mauvealert-server.postrm delete mode 100644 lib/mauve/notifiers/xmpp-smack.rb diff --git a/.hgignore b/.hgignore index 826867e..b734f59 100644 --- a/.hgignore +++ b/.hgignore @@ -6,3 +6,4 @@ ^debian/mauvealert-.*\.debhelper(.log)?$ ^debian/mauvealert-.*.substvars$ ^debian/files +^static/javascript/jquery$ diff --git a/Makefile b/Makefile index 9ec7fbd..3776678 100644 --- a/Makefile +++ b/Makefile @@ -3,11 +3,13 @@ # ## -all: man/mauveclient.1 +all: man man/mauveclient.1 man/mauveserver.1 man/mauveconsole.1 -man/%.1: bin/% +man: mkdir -p man - ruby -I lib $< --help | txt2man -t $(notdir $<) -s 1 > $@; \ + +man/%.1: bin/% + ruby -I lib $< --help | txt2man -t $(notdir $<) -s 1 > $@ clean: $(RM) -r man diff --git a/bin/mauveclient b/bin/mauveclient index 0068435..251b45b 100755 --- a/bin/mauveclient +++ b/bin/mauveclient @@ -142,6 +142,10 @@ # # mauveclient -i heartbeat -d "No heartbeat received for 1.2.3.4. Could be down!" -s "heartbeat failed" -c -r +10m # +# SEE ALSO +# +# mauveconsole(1), mauveserver(1) +# # AUTHOR # # Patrick J Cherry diff --git a/bin/mauveconsole b/bin/mauveconsole index debe5af..5a16a7e 100755 --- a/bin/mauveconsole +++ b/bin/mauveconsole @@ -1,23 +1,70 @@ #!/usr/bin/ruby1.8 +# NAME +# +# mauveconsole -- Ruby console to query the mauvealert server directly +# +# SYNOPSIS +# +# mauveconsole [-h | --help] [] +# +# OPTIONS +# +# -h, --help Show a help message +# File to load the configuration from. If none is +# specified, then mauvealert.conf in the current +# directory is used, and failing that +# /etc/mauvealert/mauvealert.conf is used. +# +# SEE ALSO +# +# irb(1), mauveserver(1), mauveclient(1) +# +# AUTHOR +# +# Patrick J Cherry +# -require 'pp' -require 'irb' -require 'thread' -require 'mauve/configuration' +def error(msg) + STDERR.print "*** Error: #{msg}\n" + STDERR.print "*** For help, type: #{$0} -h\n" + exit 1 +end -Thread.abort_on_exception = true +# CAUTION! Kwality kode. +# +if ARGV.any?{|a| a =~ /--?h(elp)?/} + # Open the file, stripping the shebang line + lines = File.open(__FILE__){|fh| fh.readlines}[1..-1] + + lines.each do |line| + line.chomp! + break if line.empty? + puts line[2..-1].to_s + end + + exit 0 +end configuration_file = ARGV.shift -configuration_file = [".", "/etc/mauvealert/"].find{|d| File.file?(File.join(d,"mauveserver.conf")) } if configuration_file.nil? +configuration_file = [".", "/etc/mauvealert/"].collect{|x| File.join("mauveserver.conf") }.find{|d| File.file?(d)} if configuration_file.nil? configuration_file = File.expand_path(configuration_file) unless File.file?(configuration_file) - STDERR.print "Configuration file #{configuration_file} not found" - Kernel.exit 1 + error "Configuration file #{configuration_file} not found\n" end -Mauve::Configuration.current = Mauve::ConfigurationBuilder.load(configuration_file) +require 'irb' +require 'thread' +require 'mauve/configuration' + +Thread.abort_on_exception = true include Mauve +begin + Configuration.current = ConfigurationBuilder.load(configuration_file) +rescue StandardError => ex + error ex.message +end + IRB.start diff --git a/bin/mauveserver b/bin/mauveserver index 2d810b9..a5cf7b5 100755 --- a/bin/mauveserver +++ b/bin/mauveserver @@ -1,49 +1,111 @@ #! /usr/bin/ruby1.8 +# NAME +# +# mauveserver -- receive alerts from station(s) around the network +# +# SYNOPSIS +# +# mauveserver [ -h | --help ] [] +# +# OPTIONS +# +# -h, --help Show a help message +# +# File to load the configuration from +# +# SEE ALSO +# +# mauveclient(1), mauveconsole(1) +# +# AUTHOR +# +# Patrick J Cherry +# + +def error(msg) + STDERR.print "*** Error: #{msg}\n" + STDERR.print "*** For help, type: #{$0} -h\n" + exit 1 +end begin eval "Proc.new { |a,&b| }" rescue SyntaxError => no_blocks_with_procs - STDERR.print "mauveserver must have Ruby 1.8.7 or later, sorry (if you "+ - "try, you'll get a SyntaxError trying to load one of its libraries)\n" - exit 1 + error "mauveserver must have Ruby 1.8.7 or later" end - -require 'mauve/configuration' + +# CAUTION! Kwality kode. +# +if ARGV.any?{|a| a =~ /--?h(elp)?/} + # Open the file, stripping the shebang line + lines = File.open(__FILE__){|fh| fh.readlines}[1..-1] + + lines.each do |line| + line.chomp! + break if line.empty? + puts line[2..-1].to_s + end + + exit 0 +end + configuration_file = ARGV.shift -configuration_file = [".", "/etc/mauvealert/"].find{|d| File.file?(File.join(d,"mauveserver.conf")) } if configuration_file.nil? +configuration_file = [".", "/etc/mauvealert/"].collect{|x| File.join("mauveserver.conf") }.find{|d| File.file?(d)} if configuration_file.nil? configuration_file = File.expand_path(configuration_file) unless File.file?(configuration_file) - STDERR.print "Configuration file #{configuration_file} not found\n" - Kernel.exit 1 + error "Configuration file #{configuration_file} not found\n" end -Mauve::Configuration.current = Mauve::ConfigurationBuilder.load(configuration_file) +require 'mauve/configuration' + +begin + Mauve::Configuration.current = Mauve::ConfigurationBuilder.load(configuration_file) +rescue StandardError => ex + error ex.message +end %w(HUP).each do |sig| - trap("HUP") do + trap(sig) do # this blows up if you do it twice in quick succession, but don't really # care about that case as it's only for log rotation. - Mauve::Server.instance.logger.warn "#{sig} signal received. Stopping." + Mauve::Server.instance.logger.warn "#{sig} signal received. Restarting." Mauve::Server.instance.stop # # Reload configuration # - Mauve::Server.instance.logger.warn "Restarting." - begin new_config = Mauve::ConfigurationBuilder.load(configuration_file) Mauve::Configuration.current = new_config rescue BuildException => ex - Mauve::Server.instance.logger.warn "Reconfiguration failed: #{ex}. Sticking with old one." + Mauve::Server.instance.logger.error "Reconfiguration failed: #{ex}. Sticking with old one." end Mauve::Server.instance.logger.warn "Restarting." Mauve::Server.instance.start end end +%w(USR1).each do |sig| + trap(sig) do + Mauve::Server.instance.logger.warn "#{sig} signal received. Re-opening logs." + Log4r::Outputter.each_outputter do |old| + next unless old.is_a?(Log4r::FileOutputter) + + new = Log4r::FileOutputter.new(old.name, {:filename => old.filename, :trunc => false}) + new.formatter = old.formatter + new.level = old.level + + Mauve::Server.instance.logger.outputters << new + Mauve::Server.instance.logger.outputters.delete(old) + old.close + + Mauve::Server.instance.logger.debug "Opened #{new.filename}." + end + end +end + %w(QUIT TERM INT).each do |sig| trap(sig) do Mauve::Server.instance.logger.warn "#{sig} signal received. Stopping." @@ -52,5 +114,9 @@ end end end -Mauve::Server.instance.run +begin + Mauve::Server.instance.run +rescue StandardError => ex + error ex.message +end diff --git a/debian/mauvealert-server.init b/debian/mauvealert-server.init index 1f0e57f..15c287b 100644 --- a/debian/mauvealert-server.init +++ b/debian/mauvealert-server.init @@ -32,8 +32,6 @@ SCRIPTNAME=/etc/init.d/$NAME # Load the VERBOSE setting and other rcS variables . /lib/init/vars.sh -VERBOSE=1 - # Define LSB log_* functions. # Depend on lsb-base (>= 3.2-14) to ensure that this file is present # and status_of_proc is working. @@ -48,9 +46,9 @@ do_start() # 0 if daemon has been started # 1 if daemon was already running # 2 if daemon could not be started - start-stop-daemon --start --quiet --pidfile $PIDFILE --startas $DAEMON --test > /dev/null \ + start-stop-daemon --start --quiet --pidfile $PIDFILE --startas $DAEMON --chuid $RUNASUSER --test > /dev/null \ || return 1 - start-stop-daemon --start --quiet --pidfile $PIDFILE --make-pidfile --background --startas $DAEMON -- \ + start-stop-daemon --start --quiet --pidfile $PIDFILE --make-pidfile --chuid $RUNASUSER --background --startas $DAEMON -- \ $DAEMON_ARGS \ || return 2 # Add code here, if necessary, that waits for the process to be ready @@ -95,10 +93,19 @@ do_reload() { # restarting (for example, when it is sent a SIGHUP), # then implement that here. # - start-stop-daemon --stop --signal 1 --quiet --pidfile $PIDFILE --name $NAME + start-stop-daemon --stop --signal HUP --quiet --pidfile $PIDFILE --name $NAME return 0 } +# +# Function that sends a SIGUSR1 to reopen logfiles +# +do_reopenlogs() { + start-stop-daemon --stop --signal USR1 --quiet --pidfile $PIDFILE --name $NAME + return 0 +} + + case "$1" in start) [ "$VERBOSE" != no ] && log_daemon_msg "Starting $DESC" "$NAME" @@ -128,6 +135,11 @@ case "$1" in do_reload log_end_msg $? ;; + reopen-logs) + log_daemon_msg "Re-opening logs for $DESC" "$NAME" + do_reopenlogs + log_end_msg $? + ;; restart) # # If the "reload" option is implemented then remove the diff --git a/debian/mauvealert-server.logrotate b/debian/mauvealert-server.logrotate new file mode 100644 index 0000000..3885a35 --- /dev/null +++ b/debian/mauvealert-server.logrotate @@ -0,0 +1,10 @@ +/var/log/mauvealert.log { + rotate 7 + daily + compress + delaycompress + postrotate + /usr/sbin/invoke-rc.d mauvealert-server reopen-logs >/dev/null + endscript +} + diff --git a/debian/mauvealert-server.postinst b/debian/mauvealert-server.postinst new file mode 100644 index 0000000..3d1c09a --- /dev/null +++ b/debian/mauvealert-server.postinst @@ -0,0 +1,20 @@ +#!/bin/bash + +set -e + +## +# Add a mauve user +## +RUNASUSER=mauvealert + +adduser --system --no-create-home --home /nonexistent $RUNASUSER > /dev/null + +## +# Add default directories +## +for i in log lib ; do + mkdir -p /var/$i/mauvealert + chown -R $RUNASUSER:nogroup /var/$i/mauvealert +done + +#DEBHELPER# diff --git a/debian/mauvealert-server.postrm b/debian/mauvealert-server.postrm new file mode 100644 index 0000000..24fd158 --- /dev/null +++ b/debian/mauvealert-server.postrm @@ -0,0 +1,23 @@ +#!/bin/bash + +set -e + +## +# Add a mauve user +## +RUNASUSER=mauvealert + +if [ "$1" = "purge" ] ; then + ## + # Remove the system user + ## + deluser --system $RUNASUSER > /dev/null + + ## + # remove default directories + ## + rm -rf /var/log/mauvealert/ + rm -rf /var/lib/mauvealert/ +fi + +#DEBHELPER# 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 # diff --git a/mauveserver.conf b/mauveserver.conf index c17f7f7..4baec0a 100644 --- a/mauveserver.conf +++ b/mauveserver.conf @@ -5,7 +5,9 @@ # The service which listens for alert messages # server { + # # persistent data store, only sqlite3 supported at the moment + # database "sqlite3:///var/lib/mauvealert/alerts.db" listener { @@ -14,7 +16,7 @@ server { } # default is probably more than enough! - #transmission_id_expire_time 600 + # transmission_id_expire_time 600 # few options for web interface, just the TCP port number web_interface { @@ -28,44 +30,49 @@ logger { default_format "%d [ %6.6l ] [ %12.12c ] %m" -# outputter("stdout") { -# level Log4r::DEBUG -# } - outputter("file") { - filename "/var/log/mauve/mauveserver.log" + filename "/var/log/mauvealert/mauvealert.log" trunc false - level Log4r::DEBUG + level Log4r::INFO } - outputter("email") { - server "outgoing.mx.bytemark.co.uk" - subject "Mauve logger output" - from "#{ENV['USER']}@#{Socket.gethostname}" - to "patrick@bytemark.co.uk" - domain "test.mauve.bytemark.co.uk" - level Log4r::WARN - } +# outputter("stdout") { +# level Log4r::DEBUG +# } + +# outputter("email") { +# server "localhost" +# subject "Mauve logger output" +# from "mauvealert@localhost" +# to "boring@localhost" +# domain "localhost" +# level Log4r::WARN +# } } notification_method("email") { + # # email address to send from + # from "mauvealert@" + `hostname`.chomp - # smarthost + + # + # outbound smtp host + # server "localhost" - # add this to the subject of any emails we send - subject_prefix "[mauve] " - # for testing, enable this - #deliver_to_file "/tmp/alerts.txt" + # + # add this to the subject of any emails we send + # + subject_prefix "[mauvealert]" } # How to log into a jabber server # # notification_method("xmpp") { -# jid "mauvealert@jabber.org/olympus" -# password "WojIsEv8ScaufOm1" +# jid "mauvealert@chat.example.com/boo" +# password "x" # } # How to notify by SMS - we use aql.com, you'll need to write a module @@ -86,12 +93,6 @@ notification_method("email") { # alert levels. You probably want more people, see below for a more complete # example. # -# Passwords are generated like so: -# ruby-1.8.7-p72 > require 'digest/sha1' -# => true -# ruby-1.8.7-p72 > sha1 = Digest::SHA1.hexdigest('my new super secure and easy to type on phone password') -# => "729cf161621400fa63fcb3b4750441390fbface2" -# person("root") { all { email("root@localhost") } } @@ -148,6 +149,7 @@ person("root") { # } # } +# # Default notification - tell root about all alerts every hour # alert_group { diff --git a/views/_acknowledge_input.haml b/views/_acknowledge_input.haml index b6fc24b..82f3044 100644 --- a/views/_acknowledge_input.haml +++ b/views/_acknowledge_input.haml @@ -7,7 +7,10 @@ Acknowledge these alerts for %option{ :value => "wallclock" } wall-clock hours %span#ack_until_text -%input#ack_until{ :value => '', :type => :hidden, :name => 'ack_until' } +%input#ack_until{ :value => '', :type => :hidden, :name => 'ack_until' } +%br +with the note +%input#note{ :name => 'note', :type => "text"} %input{ :type => 'submit', :value => 'Go!' } :javascript // Change of value in the hours box diff --git a/views/alert.haml b/views/alert.haml index 7e7503f..d4e274f 100644 --- a/views/alert.haml +++ b/views/alert.haml @@ -47,7 +47,7 @@ %th Notifications sent out %td %ul - - @alert.changes.each do |change| + - @alert.changes.first(10).each do |change| - if change.was_relevant? %li %strong= change.level @@ -59,8 +59,8 @@ %tr %th History %td - %ul - - @alert.histories.each do |history| + %ul#histories + - @alert.histories.first(10).each do |history| %li = history.event at -- cgit v1.2.1