From 15bff4c4c0a936da52c8aa309715a07a46162ee2 Mon Sep 17 00:00:00 2001 From: Sven Velt Date: Thu, 23 Sep 2010 10:11:48 +0200 Subject: [PATCH] WIP: Obsessing/distributed setup with Nag(ix)SC Signed-off-by: Sven Velt --- obsess.README | 53 +++++++++++++++++++++++++++++++++ obsess_daemon.py | 77 ++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 130 insertions(+) create mode 100644 obsess.README create mode 100755 obsess_daemon.py diff --git a/obsess.README b/obsess.README new file mode 100644 index 0000000..72c0edf --- /dev/null +++ b/obsess.README @@ -0,0 +1,53 @@ +nagios.cfg: +=========== + +obsess_over_services=1 +ocsp_command=ocsp2out +obsess_over_hosts=1 +ochp_command=ochp2out + + + +commands: +========= + +define command { + command_name ocsp2out + command_line echo >>/tmp/nagixsc.spool/new/$TIMET$ LASTSERVICECHECK::$LASTSERVICECHECK$ HOSTNAME::\'$HOSTNAME$\' SERVICEDESC::\'$SERVICEDESC$\' SERVICESTATEID::$SERVICESTATEID$ SERVICEOUTPUT::\'$SERVICEOUTPUT$\' LONGSERVICEOUTPUT::\'$LONGSERVICEOUTPUT$\' +} + +define command { + command_name ochp2out + command_line echo >>/tmp/nagixsc.spool/new/$TIMET$ LASTHOSTCHECK::$LASTHOSTCHECK$ HOSTNAME::\'$HOSTNAME$\' HOSTSTATEID::$HOSTSTATEID$ HOSTOUTPUT::\'$HOSTOUTPUT$\' LONGHOSTOUTPUT::\'$LONGHOSTOUTPUT$\' +} + + +Vorteile: +========= + +- Anders als in der originalen Dokumentation wird NICHT noch eine Shell + gestartet, die die Return-Codes analysiert und dann mit Hilfe von "printf" + den String formatiert. +- Das Original-Skript ruft "send_nsca" direkt auf. Dies wiederum blockiert den + Nagios so lange, bis das NSCA-Netzwerkpaket verschickt werden konnte (Man + bedenke das Timeout, wenn der Server nicht erreicht werden kann). + Das Wegschreiben der Spool-Datei hier macht die von Nagios sowieso geforkte + und gestartete Shell. Die Blockierung des Nagios-Prozess (sollte) ist somit + minimal. +- Nagios schreibt mehrere Check-Ergebniss praktisch auf einmal weg (vgl. + Zeitstempel). NSCA schickt alle Pakete einzeln (für jedes einen + TCP-Handshake...), Nag(ix)SC packt die Ergebnisse aus einem Spool-File in + ein XML und schickt mehrere bis viele Check-Ergebnisse auf einmal los. +- Das Senden der XML-Files passiert unabhängig von Nagios durch einen eigenen + Prozess ("obsess_daemon.py") + + +Hinweis: +======== + +- "obsess_daemon.py" ist noch kein richtiger Daemon, einfach an der + Kommandozeile start und gut laufen lassen (Debug-Ausgaben!) +- Zum "auf die Finger guggen": + % cd /tmp/nagixsc.spool + % watch -n2 "cat */*[0-9] |wc -l; (for F in xmlout/*; do ~/src/nagixsc/nagixsc_read_xml.py -f \$F; done)|grep -c RetCode" + diff --git a/obsess_daemon.py b/obsess_daemon.py new file mode 100755 index 0000000..1712c4e --- /dev/null +++ b/obsess_daemon.py @@ -0,0 +1,77 @@ +#!/usr/bin/python + +import os +import re +import time + +############################################################################## +from nagixsc import * +############################################################################## + +def check_dir(dirpath): + if not os.path.isdir(dirpath): + # dirpath does not exist, try to create it + try: + os.path.os.mkdir(dirpath, 0777) # FIXME + except OSError: + print 'Could not create directory "%s"!' % dirpath + sys.exit(1) + + if not os.access(dirpath,os.W_OK): + # dirpath is not writeable + print 'No write access to directory "%s"!' % dirpath + sys.exit(1) + +############################################################################## + +spoolpath_base = '/tmp/nagixsc.spool' +spoolpath_new = os.path.join(spoolpath_base, 'new') +spoolpath_work = os.path.join(spoolpath_base, 'work') +spoolpath_done = os.path.join(spoolpath_base, 'done') + +for d in [spoolpath_base, spoolpath_new, spoolpath_work, spoolpath_done]: + check_dir(d) + +# Output XML files to this directory +outdir = os.path.join(spoolpath_base, 'xmlout') +check_dir(outdir) + +service_analyzer = re.compile("^LASTSERVICECHECK::'?(\d+)'?\s+HOSTNAME::'?([^']+)'?\s+SERVICEDESC::'?([^']+)'?\s+SERVICESTATEID::'?(\d+)'?\s+SERVICEOUTPUT::'?([^']*)'?\s+LONGSERVICEOUTPUT::'?([^']*)'?$") +host_analyzer = re.compile("LASTHOSTCHECK::'?(\d+)'?\s+HOSTNAME::'?([^']+)'?\s+HOSTSTATEID::'?(\d+)'?\s+HOSTOUTPUT::'?([^']*)'?\s+LONGHOSTOUTPUT::'?([^']*)'?$") + + +while True: + if os.listdir(spoolpath_new): + checks = [] + files_done = [] + for filename in os.listdir(spoolpath_new): + spoolfile = os.path.join(spoolpath_work, filename) + os.rename(os.path.join(spoolpath_new, filename), spoolfile) + + # Work with file + f = open(spoolfile) + + print 'Read ' + spoolfile + for line in f: + if line.startswith('LASTSERVICECHECK'): + m = service_analyzer.match(line) + if m: + checks.append({'host_name':m.group(2), 'service_description':m.group(3), 'returncode':m.group(4), 'output':'\n'.join(m.group(5,6)), 'timestamp':m.group(1)}) + + elif line.startswith('LASTHOSTCHECK'): + m = host_analyzer.match(line) + if m: + checks.append({'host_name':m.group(2), 'service_description':None, 'returncode':m.group(3), 'output':'\n'.join(m.group(4,5)), 'timestamp':m.group(1)}) + + f.close() + files_done.append(filename) + + outfilename = str(int(time.time())) + '.xml' + xmldoc = xml_from_dict(checks) + xmldoc.saveFile(os.path.join(outdir, outfilename)) # FIXME + for filename in files_done: + os.rename(os.path.join(spoolpath_work, filename), os.path.join(spoolpath_done, filename)) + print 'Written ' + outfilename + + time.sleep(5) + -- 2.30.2