43
NAGIOSPLUGIN EINE PYTHON-KLASSENBIBLIOTHEK FÜR NAGIOS/ICINGA- PLUGINS Christian Kauhaus [email protected]

nagiosplugin - eine Python-Bibliothek für Monitoring-Plugins

Embed Size (px)

DESCRIPTION

Auch wenn in der letzten Zeit sehr viel Bewegung in die Monitoring-Szene gekommen ist (#monitoringsucks etc.), werden die Platzhirsche Nagios/Icinga und ihre Standards auf absehbare Zeit nicht verschwinden. Das Nagios-Plugin-API stellt eine sehr weit verbreitete Schnittstelle zur Anbindung einzelner Checks an Monitoring-Systeme dar. Obwohl das API in den Grundzügen sehr einfach ist, ist der Programmieraufwand für vollständig konforme Plugins erstaunlich hoch. Die nagiosplugin-Bibliothek nimmt dem Entwickler viele Details ab, so dass er sich auf den Inhalt seiner Checks konzentrieren kann. Der Vortrag führt in das Schreiben von Nagios-kompatiblen Plugins ein, zeigt den typischen Aufbau von Nagios-Plugins und das Grundprinzip eigener Plugins. Die Konfiguration und der Betrieb von Monitoring-Systemen im Großen sollen nicht thematisiert werden. Video: http://pyvideo.org/video/1460/nagiosplugin-eine-python-bibliothek-fur-monitor Konferenzseite: https://2012.de.pycon.org/programm/schedule/sessions/45/ Projekt-Homepage: https://projects.gocept.com/projects/nagiosplugin/wiki

Citation preview

Page 1: nagiosplugin - eine Python-Bibliothek für Monitoring-Plugins

NAGIOSPLUGINEINE PYTHON-KLASSENBIBLIOTHEK FÜR NAGIOS/ICINGA-

PLUGINSChristian Kauhaus

[email protected]

Page 2: nagiosplugin - eine Python-Bibliothek für Monitoring-Plugins

(Lloyd S. Nelson)

“ The most important figures that oneneeds for management are unknown or

unknowable. ”

Page 3: nagiosplugin - eine Python-Bibliothek für Monitoring-Plugins

CHRISTIAN KAUHAUSseit 2008 bei goceptSysadminHosting/Data Center

FlyingCircus.io

Page 4: nagiosplugin - eine Python-Bibliothek für Monitoring-Plugins

ÜBERBLICKIntroKonzepteBasics

DatenerhebungDatenbewertungPräsentation

AdvancedLogging & OutputPersistente DatenFehlerbehandlung

Fazit

Page 5: nagiosplugin - eine Python-Bibliothek für Monitoring-Plugins

BEIPACKZETTELDIESER VORTRAG ENTHÄLT

Einführung in nagiospluginviele Code-BeispieleLive-Demos

DIESER VORTRAG ENTHÄLT NICHT

die gesamte nagiosplugin-APIKonfiguration von Nagios/Icinga-Servern

Page 6: nagiosplugin - eine Python-Bibliothek für Monitoring-Plugins

INTROPlugins sind primäre Methode der

Informationsgewinnung bei Nagios/Icinga

Input: KommandozeileOutput: Text auf stdout, Exit-CodePlugin API:

Plugin Development Guidelines:http://nagios.sourceforge.net/docs/3_0/pluginapi.html

http://nagiosplug.sourceforge.net/developer-guidelines.html

Page 7: nagiosplugin - eine Python-Bibliothek für Monitoring-Plugins

PLUGIN SCHREIBEN? IST DOCH EASY!#!/bin/sh# 31131 disk plugin codez# (C) 1999,2004-2006,2011 by wArEzGuY# if you don't understand this go away

echo "wArEzGuY's kewl disk plugin is running!!!"

df /srv/app01/data | grep '̂/' | awk '{ print $3 }' | \ grep '[1-5].....' || { echo "OMG!!! *** disk is screwed!!!"; exit 2}

echo "disk is ok"exit 0

# XXX should never reach this

Page 8: nagiosplugin - eine Python-Bibliothek für Monitoring-Plugins

NAGIOS PLUGIN API

timeout standard options output spec

exit codes range syntaxperformance data multi-threshold status line

long output

Page 9: nagiosplugin - eine Python-Bibliothek für Monitoring-Plugins

BEISPIEL: OUTPUT SPEC

CHECK - status line | perf1 perf2 long output long output | perf3 perf4 perf5 perf6

Page 10: nagiosplugin - eine Python-Bibliothek für Monitoring-Plugins

BEISPIEL: RANGE-SYNTAX

9-6:8~:3-2.25:@5:7.5

Page 11: nagiosplugin - eine Python-Bibliothek für Monitoring-Plugins

NAGIOSPLUGIN IST...Python-KlassenbibliothekOpen Source (ZPL-Lizenz)entstanden aus -Eigenbedarfseit 2010 kontinuierlich weiterentwickeltPython 3-kompatibel

Release-Stand:

alte 0.4.x API wird nicht mehr weiterentwickeltInhalt des Vortrags neue 1.0 API

gocept

Page 12: nagiosplugin - eine Python-Bibliothek für Monitoring-Plugins

KONZEPTETerminlogie bei #monitoringsucks –

ResourceMetricContextEventAction

watch your language

Page 13: nagiosplugin - eine Python-Bibliothek für Monitoring-Plugins

KONZEPTE IM NAGIOS-KONTEXT

Page 14: nagiosplugin - eine Python-Bibliothek für Monitoring-Plugins

ZENTRALE KLASSEN

Page 15: nagiosplugin - eine Python-Bibliothek für Monitoring-Plugins

BASICS #1: DATENERHEBUNG

Page 16: nagiosplugin - eine Python-Bibliothek für Monitoring-Plugins

RESOURCEDomain ModelSubklasse von Resourceprobe() erzeugt Metriken

class Resource:

@property def name(self): return self.__class__.__name__

def probe(self): return []

Page 17: nagiosplugin - eine Python-Bibliothek für Monitoring-Plugins

BEISPIEL: CHECK_WORLDimport nagiosplugin

class World(nagiosplugin.Resource):

def probe(self): return [ nagiosplugin.Metric('world', True, context='null') ]

def main(): check = nagiosplugin.Check(World()) check.main()

if __name__ == '__main__': main()

Page 18: nagiosplugin - eine Python-Bibliothek für Monitoring-Plugins

METRICStrukturiertes Value-Objekt für einzelnen Datenpunkt

class Metric:

def __init__(self, name, value, uom=None, min=None, max=None, context=None): ...

Page 19: nagiosplugin - eine Python-Bibliothek für Monitoring-Plugins

BEISPIEL: CHECK_LOADclass Load(nagiosplugin.Resource):

def __init__(self, percpu=False): self.percpu = percpu

def cpus(self): return int(subprocess.check_output(['nproc']))

def probe(self): with open('/proc/loadavg') as loadavg: load = loadavg.readline().split()[0:3] cpus = self.cpus() if self.percpu else 1 load = [float(l) / cpus for l in load] for i, period in enumerate([1, 5, 15]): yield nagiosplugin.Metric('load%d' % period, load[i], min=0, context='default')

Page 20: nagiosplugin - eine Python-Bibliothek für Monitoring-Plugins

BASICS #2: DATENBEWERTUNG

Page 21: nagiosplugin - eine Python-Bibliothek für Monitoring-Plugins

CONTEXTerzeugt Result aus Metric und Resourceerzeugt Performance Dataerzeugt Klartext-Beschreibung

class Context:

def __init__(self, name, ...): ...

def evaluate(self, metric, resource): return Result(...)

def performance(self, metric, resource): return Performance(...)

def describe(self, metric): return '...'

Page 22: nagiosplugin - eine Python-Bibliothek für Monitoring-Plugins

SCALARCONTEXTHäufig gebrauchter Spezialfallwarning und critical Ranges

Verwendung direkt in Check-Initialisierung:

class ScalarContext(Context):

def __init__(self, name, warning, critical, ...): ...

check = nagiosplugin.Check( nagiosplugin.ScalarContext('load', args.warning, args.critical), ...)

Page 23: nagiosplugin - eine Python-Bibliothek für Monitoring-Plugins

ZUORDNUNG METRIC/CONTEXTJede Metric benennt den zuständigen Context

Standard-Contexts:

null - tut gar nichtsdefault - gibt Performance-Daten aus

# Load.probe() for period, i in zip([1, 5, 15], itertools.count()): yield nagiosplugin.Metric('load%d' % period, load[i], min=0, context='load')

# main()check = nagiosplugin.Check( Load(), nagiosplugin.ScalarContext('load', args.warning, args.critical), ...)

Page 24: nagiosplugin - eine Python-Bibliothek für Monitoring-Plugins

BASICS #3: PRÄSENTATION

Page 25: nagiosplugin - eine Python-Bibliothek für Monitoring-Plugins

SUMMARYStatuszeile ist wichtig!

erscheint in Mails, in SMS, auf Pagerin 80-140 Zeichen die „Message“ herüberbringenmuss nachts 3:30 Uhr verständlich sein

Page 26: nagiosplugin - eine Python-Bibliothek für Monitoring-Plugins

NICHT HILFREICH

Page 27: nagiosplugin - eine Python-Bibliothek für Monitoring-Plugins

SUMMARY – STANDARDIMPLEMENTIERUNGclass Summary:

def ok(self, results): return str(results[0])

def problem(self, results): try: return str(results.first_significant) except IndexError: return 'no check results'

def verbose(self, results): msgs = [] for result in results: if result.state == Ok: continue msgs.append('{}: {}'.format(result.state, result)) return msgs

Page 28: nagiosplugin - eine Python-Bibliothek für Monitoring-Plugins

BEISPIEL: CHECK_LOADclass LoadSummary(nagiosplugin.Summary):

def __init__(self, percpu): self.percpu = percpu

def ok(self, results): if self.percpu: what = 'loadavg per cpu' else: what = 'loadavg' return '{} is {}'.format(what, ', '.join( str(results[r].metric) for r in ['load1', 'load5', 'load15']))

Page 29: nagiosplugin - eine Python-Bibliothek für Monitoring-Plugins

ADVANCED #1: LOGGING & OUTPUTSetup:

Logging:

def main(): ... argp.add_argument('-v', '--verbose', action='count', default=0, help='increase verbosity') ... check.main(verbose=args.verbose)

def list_users(self): logging.info('querying users with "%s" command', self.who_cmd) users = [] ...

Page 30: nagiosplugin - eine Python-Bibliothek für Monitoring-Plugins

VERBOSE=0

Status und Perfdata auf einer ZeileLoglevel warning und höherSummary.verbose() wird nicht angezeigt

$ check_usersUSERS OK - 4 users logged in | total=4;;;0 unique=1;;;0

Page 31: nagiosplugin - eine Python-Bibliothek für Monitoring-Plugins

VERBOSE=1

mehrzeilige Ausgabesollte Standard sein für Server, die long outputverarbeitenLoglevel warning und höherSummary.verbose() wird angezeigt

$ check_users -vUSERS OK - 4 users logged inusers: ckauhaus, ckauhaus, ckauhaus, ckauhaus| total=4;;;0 unique=1;;;0

Page 32: nagiosplugin - eine Python-Bibliothek für Monitoring-Plugins

VERBOSE=2

Konfigurationsinformationen zum Pluginz.B. Commandlines externer AufrufeLoglevel info und höher

$ check_users.py -vvUSERS OK - 4 users logged inusers: ckauhaus, ckauhaus, ckauhaus, ckauhausquerying users with "who" command (check_users.py:34)| total=4;;;0 unique=1;;;0

Page 33: nagiosplugin - eine Python-Bibliothek für Monitoring-Plugins

VERBOSE=3

Debugging-Informationenz.B. ZwischenergebnisseLoglevel debug und höher

$ check_users.py -vvvUSERS OK - 4 users logged inusers: ckauhaus, ckauhaus, ckauhaus, ckauhausquerying users with "who" command (check_users.py:34)who output: b'ckauhaus tty1 2012-10-29 12:36' (check_users.py:38)...| total=4;;;0 unique=1;;;0

Page 34: nagiosplugin - eine Python-Bibliothek für Monitoring-Plugins

FORMATIERUNG VON METRIKENContext ist für „seine“ Metriken zuständig

Variante 1: String-Template

Variante 2: Callable

Context(..., fmt_metric='{name} is {valueunit}')

def format_usercount(metric, context): return '...'

Context(..., fmt_metric=format_usercount)

Page 35: nagiosplugin - eine Python-Bibliothek für Monitoring-Plugins

ADVANCED #2: PERSISTENTE DATENZustand zwischen Plugin-Aufrufen behalten

CookieLogTail

Page 36: nagiosplugin - eine Python-Bibliothek für Monitoring-Plugins

COOKIEpersistentes dictSerialisierung mit JSONLocking

Inhalt von statefile:

with nagiosplugin.Cookie(self.statefile) as cookie: self.timestamp = cookie.get('last_seen', '') metrics = self.do_something() cookie['last_seen'] = self.timestamp

{ "last_seen": "2012-10-28 12:08:25"}

Page 37: nagiosplugin - eine Python-Bibliothek für Monitoring-Plugins

LOGTAILInkrementelles Lesen von wachsenden Logfiles

baut auf Cookie auferkennt Log-RotationWiederaufsetzen nach Exceptions

def parse_log(self): cookie = nagiosplugin.Cookie(self.statefile) with nagiosplugin.LogTail(self.logfile, cookie) as lf: for line in lf: ...

Page 38: nagiosplugin - eine Python-Bibliothek für Monitoring-Plugins

ADVANCED #3: FEHLERBEHANDLUNGWas ist, wenn es nicht so läuft wie geplant?

Wichtige Fehlerklassen:

Resource nicht da/nicht abfragbarFehlerhafte Kommandozeilen-ParameterUmgebungsfehlerProgrammierfehler

Page 39: nagiosplugin - eine Python-Bibliothek für Monitoring-Plugins

@NAGIOSPLUGIN.GUARDEDSchützt die main()-Funktion bei Exceptions:

Exit-Status 3API-konforme AusgabeTraceback bei verbose ≥ 1

@nagiosplugin.guardeddef main(): argp = argparse.ArgumentParser() argp.add_argument(...) args = argp.parse_args() check = nagiosplugin.Check(Load(args.percpu), ...) check.main()

Page 40: nagiosplugin - eine Python-Bibliothek für Monitoring-Plugins

BEISPIEL: EXCEPTION IN PROBE()

Ausgabe (verbose=0):

class Fail(nagiosplugin.Resource):

def probe(self): raise RuntimeError("I'm feeling bad")

@nagiosplugin.guardeddef main(): argp = argparse.ArgumentParser() argp.add_argument('-v', action='count', default=0) args = argp.parse_args() check = nagiosplugin.Check(Fail()) check.main(args.verbose)

$ check_fail.pyFAIL UNKNOWN: RuntimeError: I'm feeling bad# exit 3

Page 41: nagiosplugin - eine Python-Bibliothek für Monitoring-Plugins

FAZITMit nagiosplugin macht das

Schreiben von Plugins beinahe Spaß. ;-)

Trennung der Verantwortlichkeitenwartbarer, objekt-orientierter Codevolle Unterstützung der Plugin-APIkleine Helferrobustes Verhalten im Fehlerfall

Page 42: nagiosplugin - eine Python-Bibliothek für Monitoring-Plugins

USE THE SOURCE, LUKE

Download:

Code:

Wiki/Tracker/Forum:

http://pypi.python.org/pypi/nagiosplugin

https://bitbucket.org/gocept/nagiosplugin

https://projects.gocept.com/projects/nagiosplugin/wiki

Page 43: nagiosplugin - eine Python-Bibliothek für Monitoring-Plugins

DANKE!FRAGEN?