aboutsummaryrefslogtreecommitdiff
path: root/bin
diff options
context:
space:
mode:
Diffstat (limited to 'bin')
-rwxr-xr-xbin/jconsole23
-rwxr-xr-xbin/jmauveserver65
-rwxr-xr-xbin/mauveclient172
-rwxr-xr-xbin/mauveconsole23
-rwxr-xr-xbin/mauveserver71
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
+#
+