diff options
Diffstat (limited to 'bin')
-rwxr-xr-x | bin/jconsole | 23 | ||||
-rwxr-xr-x | bin/jmauveserver | 65 | ||||
-rwxr-xr-x | bin/mauveclient | 172 | ||||
-rwxr-xr-x | bin/mauveconsole | 23 | ||||
-rwxr-xr-x | bin/mauveserver | 71 |
5 files changed, 354 insertions, 0 deletions
diff --git a/bin/jconsole b/bin/jconsole new file mode 100755 index 0000000..6e638ad --- /dev/null +++ b/bin/jconsole @@ -0,0 +1,23 @@ +#!/usr/bin/env jruby + +require 'pp' +pp $: + +Thread.abort_on_exception = true +require 'irb' +require 'thread' + +# hack for delving into test-generated configurations +class AlertAndNotificationLogic; Alerts = Queue.new; end + +require 'mauve/configuration' +include Mauve +#raise "must specify config file" unless ARGV.length > 0 +unless ARGV.length > 0 + STDERR.print("You must specify a configuration file as $arg[1]\n") + STDERR.print(" eg: ./mauve_starter ./bin/console ./test/local.conf\n") + exit 1 +end +Configuration.current = ConfigurationBuilder.load(ARGV.shift) +IRB.start + diff --git a/bin/jmauveserver b/bin/jmauveserver new file mode 100755 index 0000000..9cdd26f --- /dev/null +++ b/bin/jmauveserver @@ -0,0 +1,65 @@ +#!/usr/bin/env jruby + +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 +end + +require 'mauve/configuration' +include Mauve + +configuration_file = ARGV[0] +if !configuration_file + if File.exists?("/etc/mauvealert/mauveserver.conf") + configuration_file = "/etc/mauvealert/mauveserver.conf" + else + STDERR.print "Syntax: #{$0} <configuration filename>\n" + exit 1 + end +end +Configuration.current = ConfigurationBuilder.load(configuration_file) + +class RestartSignalReceived < Exception; end +trap("HUP") 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. + Thread.main.raise(RestartSignalReceived.new) +end + +# Start canary thread. +#require 'canary' +#Canary.start(1, Log) + +# Main loop +@logger = Log4r::Logger.new "mauve::server<#{Process.pid}>" +loop do + begin + Configuration.current.server.run + rescue Interrupt + @logger.info "Interrupted by user, exiting" + Configuration.current.close + exit 0 + rescue RestartSignalReceived => ex + @logger.info "Restart signal received, reloading the configuration" + begin + new_configuration = ConfigurationBuilder.load(configuration_file) + rescue Exception => ex + @logger.error "Error reloading configuration, reusing old one: #{ex}" + @logger.debug ex.backtrace.join("\n") + end + + Configuration.current.close + Configuration.current = new_configuration + rescue Exception => ex + @logger.fatal("Uncaught #{ex.class} exception, will try to log") + @logger.fatal("Class: #{ex.class} "+ + "Message: #{ex.message} "+ + "Backtrace: #{ex.backtrace.join("\n")}") + exit 9 + end +end + + diff --git a/bin/mauveclient b/bin/mauveclient new file mode 100755 index 0000000..d513926 --- /dev/null +++ b/bin/mauveclient @@ -0,0 +1,172 @@ +#! /usr/bin/ruby1.8 +# == Synopsis +# +# mauvesend: send alert(s) to a given alert station +# +# == Usage +# +# mauvesend [destination] +# [--source | -o <source>] [--replace | -p] [--verbose | -v] +# [--id <alert ID> [alert options] ... ] +# +# <destination>: +# where the alert should go, can be one of: +# SRV record from DNS (we add _mauvealert._udp to record name) +# normal hostname (i.e. A record) +# IP address:port number +# +# if no destination is supplied, reads parameter from file +# /etc/mauvealert/mauvesend.destination (otherwise throws an error). +# +# --source | -o <source>: +# identify the source of the alert (defaults to hostname, but you might +# want to name your monitoring systems more explicitly). +# +# --replace | -p: +# Send an update replacing all other alerts for this source - any previous +# alerts not specified in this update are assumed to be cleared. If you +# specify this option, you don't have to supply *any* alerts to raise or +# clear (in which case all alerts from that source will be cleared). +# +# --verbose | -v: +# If you specify this option once, it will print the transmission ID +# of the packet for debugging. If you specify it twice, it will print +# the entire data structure. +# +# You can specify any number of alerts in an update - every time you specify +# --id starts a new alert. +# +# --id | -i <alert ID>: +# alert ID; unique specified for each alert raised. +# +# --summary | -s <summary>: +# text for humans describing the nature of the alert, first 100 characters +# are only ones guaranteed to make it to pagers, twitter, SMS etc. +# +# --detail | -d <detail>: +# HTML fragment describing the alert in more detail, no limit on length. +# +# --subject | -u <subject>: +# set the subject of the alert (i.e. the server/entity that this alert +# concerns). +# +# --clear | -c <time>: +# mark the alert to be cleared at the given time, or +N where N is a number +# of seconds, or 'now'. If not supplied, the alert is deemed to be raised +# until explicitly cleared. +# +# --raise | -r <time>: +# mark the alert to be (re)raised at the given time. If not supplied, the +# alert will be raised immediately. +# + +require 'getoptlong' +require 'mauve/sender' +require 'mauve/proto' +require 'mauve/mauve_time' +require 'pp' + +def error(msg) + STDERR.print "*** Error: #{msg}\n" + STDERR.print "*** For help, type: #{$0} -h\n" + exit 1 +end + +def parse_time_spec(spec) + now = Mauve::MauveTime.now + + return now if spec == 'now' + + case spec[0] + when ?+ then multiplier = 1 + when ?- then multiplier = -1 + else + return Mauve::MauveTime.parse(spec) + end + multiplier *= case spec[-1] + when ?m then 60 + when ?h then 3600 + when ?d then 86400 + else + 1 + end + + now + spec[1..-1].to_i * multiplier +end + +update = Mauve::Proto::AlertUpdate.new +update.replace = false +update.alert = [] +message = nil +verbose = 0 +help = false + +GetoptLong.new( + ['-h', '--help', GetoptLong::NO_ARGUMENT], + ['-o', '--source', GetoptLong::REQUIRED_ARGUMENT], + ['-p', '--replace', GetoptLong::NO_ARGUMENT], + ['-i', '--id', GetoptLong::REQUIRED_ARGUMENT], + ['-s', '--summary', GetoptLong::REQUIRED_ARGUMENT], + ['-u', '--subject', GetoptLong::REQUIRED_ARGUMENT], + ['-c', '--clear', GetoptLong::REQUIRED_ARGUMENT], + ['-r', '--raise', GetoptLong::REQUIRED_ARGUMENT], + ['-d', '--detail', GetoptLong::REQUIRED_ARGUMENT], + ['-v', '--verbose', GetoptLong::NO_ARGUMENT] +).each do |opt,arg| + case opt + when '-h' + help = true + when '-p' + update.replace = true + when '-i' + message = Mauve::Proto::Alert.new + message.id = arg + update.alert << message + when '-o' + error "Can only specify one source" if update.source + update.source = arg + when '-v' + verbose += 1 + else + error "Must specify --id before message" unless message + case opt + when '-s' then message.summary = arg + when '-u' then message.subject = arg + when '-d' then message.detail = arg + when '-c' then message.clear_time = parse_time_spec(arg).to_i + when '-r' then message.raise_time = parse_time_spec(arg).to_i + else + error "Unknown option #{opt}" + end + end +end + + +# CAUTION! Kwality kode. +# +if help + # Open the file, stripping the shebang line + lines = File.open(__FILE__){|fh| fh.readlines}[2..-1] + + lines.each do |line| + line.chomp! + break if line.empty? + puts line[2..-1].to_s + end + + exit 0 +end + + +error "No alerts specified" unless !update.alert.empty? || update.replace + +update.transmission_id = rand(2**63) + +begin + Mauve::Sender.new(ARGV).send(update, verbose) +rescue ArgumentError => ae + error ae.message +rescue Protobuf::NotInitializedError => bad + error "Alert not initialized fully - you must supply an ID" +end + diff --git a/bin/mauveconsole b/bin/mauveconsole new file mode 100755 index 0000000..d375139 --- /dev/null +++ b/bin/mauveconsole @@ -0,0 +1,23 @@ +#!/usr/bin/ruby1.8 + +require 'pp' +pp $: + +Thread.abort_on_exception = true +require 'irb' +require 'thread' + +# hack for delving into test-generated configurations +class AlertAndNotificationLogic; Alerts = Queue.new; end + +require 'mauve/configuration' +include Mauve +#raise "must specify config file" unless ARGV.length > 0 +unless ARGV.length > 0 + STDERR.print("You must specify a configuration file as $arg[1]\n") + STDERR.print(" eg: ./mauve_starter ./bin/console ./test/local.conf\n") + exit 1 +end +Configuration.current = ConfigurationBuilder.load(ARGV.shift) +IRB.start + diff --git a/bin/mauveserver b/bin/mauveserver new file mode 100755 index 0000000..c576c85 --- /dev/null +++ b/bin/mauveserver @@ -0,0 +1,71 @@ +#! /usr/bin/ruby1.8 + +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 +end + +require 'mauve/configuration' +include Mauve + +configuration_file = ARGV[0] +if configuration_file.nil? + %w(/etc/mauvealert/mauveserver.conf mauveserver.conf).each do |configuration_file| + break if File.exists?(configuration_file) + end +end + +unless File.exists?(configuration_file) + if ARGV[0] + STDERR.print "Configuration file #{configuration_file} not found" + else + STDERR.print "Syntax: #{$0} <configuration filename>\n" + end + exit 1 +end + +Configuration.current = ConfigurationBuilder.load(configuration_file) + +class RestartSignalReceived < Exception; end +class TerminateSignalReceived < Exception; end + +%w(HUP).each do |sig| + trap("HUP") 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. + Configuration.current.logger.warn "#{sig} signal received. Restarting." + Configuration.current.server.stop + # + # Reload configuration + # + Configuration.current = ConfigurationBuilder.load(configuration_file) + Configuration.current.server.start + end +end + +%w(QUIT TERM INT).each do |sig| + trap(sig) do + Configuration.current.logger.warn "#{sig} signal received. Exiting." + Configuration.current.server.stop + exit 0 + end +end + +#begin + Mauve::Server.instance.run +#rescue SystemExit + # Woo! +# exit 0 +#rescue Exception => ex +# [ex.class.to_s, ex.to_s, ex.backtrace.join("\n")].each do |s| +# Configuration.current.logger.fatal s +# warn s +# end +# +# exit 1 +#end +# + |