Mit Hilfe selbst geschriebener Plugins spannt der clevere Perl-Programmierer das Netzwerk-Monitoring-Tool Nagios für vielfältige Überwachungsaufgaben ein.
Was tun, wenn die technisch eher desinteressierte Lebenspartnerin aus dem Nebenzimmer ruft: “Mein Internet geht nicht!” Mühsam zu erforschen, ob der Router ordnungsgemäß mit dem Serviceprovider kommuniziert und der DNS-Server erreichbar ist, wäre eine Möglichkeit. Viel einfacher gestaltet sich die Fehlersuche allerdings, wenn eine Software die wichtigsten Funktionen stets im Blick behält und das Ergebnis auf einer Webseite wie beispielsweise in Abbildung 1 präsentiert.

Abbildung 1: Die Nagios-Übersichtsseite zeigt an, dass lokale Tests fehlerlos durchlaufen, aber der Router und alle hinter ihm liegenden Systeme nicht ansprechbar sind.
Für solche Monitoring-Aufgaben bietet sich das Open-Source-Tool Nagios an. Die Entwickler stellen auf [5] viele Plugins bereit, die Websites, Datenbanken, Netzwerke und vieles mehr überwachen. Für spezielle Bedürfnisse schneidert sich der Admin einfach eigene Plugins nach Maß.
Nagios kann zum Beispiel laufend prüfen, ob ein Hostingprovider dem Kunden einen performanten Server mit genügend Spielraum zur Verfügung stellt, statt die vermieteten Rechner mit zu vielen Websites zu überfordern. Hat die Nagios-Installation auf dem lokalen Rechner aus Sicherheitsgründen keinen direkten Shellzugang zum fraglichen Host beim Provider, installiert der Kunde dort einfach einen Agenten.
IO-Statistik
Dafür eignet sich das Skript »iostat.cgi« (Listing 1), abgelegt im CGI-Verzeichnis des zu untersuchenden Webservers. Auf einen HTTP-Request hin ruft es das Kommando »iostat« auf und sendet dessen Ergebnisse zurück an das anfordernde Nagios-Plugin. Dies interpretiert das Ergebnis und teilt der Nagios-Applikation über den Exit-Code mit, ob alle Werte im grünen Bereich liegen oder ein Problem aufgetreten ist (Tabelle 1).
|
Listing 1: |
|---|
01 #!/usr/bin/perl -w
02 use strict;
03 use Sysadm::Install qw(:all);
04 use CGI qw(:all);
05 use Regexp::Common;
06
07 my($stdout, $stderr, $rc) =
08 tap "iostat", 1, 2;
09
10 $stdout =~ /avg-cpu.*?avg-cpu/gs;
11
12 print header();
13
14 for my $key (qw(user nice sys
15 iowait idle)) {
16 if($stdout =~
17 /G.*?($RE{num}{real})/gs) {
18 printf "%s %s ", $key, $1;
19 }
20 }
|
|
Tabelle 1: |
||
|---|---|---|
|
Exit-Wert |
Text |
Bedeutung |
|
OK |
Alles im grünen Bereich |
|
|
1 |
WARNING |
Serviceproblem |
|
2 |
CRITICAL |
Kritisches Serviceproblem |
|
3 |
UNKNOWN |
Problem mit dem Plugin |
Das CGI-Skript »iostat.cgi« ruft über die Funktion »tap« des CPAN-Moduls Sysadm::Install das Kommando »iostat« mit den Werten 1 und 2 auf (Zeile 8). Wegen des Intervall-Wertes »1« und des Count-Wertes »2« führt es zwei Messungen von CPU-Performance sowie Festplatten-IO durch und erzeugt eine Ausgabe gemäß Abbildung 3.
Die erste Messung gibt Mittelwerte seit dem letzten Reboot zurück, während die zweite die für Nagios interessanteren aktuellen Werte zeigt, die Iostat über eine Sekunde mittelt. Die Spalte »%idle« gibt an, wie lange die CPU frei zur Verfügung stand, und »%iowait« misst, wie lange die CPU auf die Festplatte warten musste. Aus der Sicht des Kunden ist also ein hoher Wert für »%idle« ebenso günstig wie ein möglichst geringer Wert für »%iowait«.
Das Skript (Listing 1) liest die Ausgabe von »iostat«, wirft die erste Messung weg, parst mit dem regulären Ausdruck »{num}{real}« aus dem Regexp::Common-Fundus die Zahlenwerte und gibt (nach dem obligatorischen HTTP-Header) den Text »user 2.99 nice 0.00 sys 0.00 iowait 0.00 idle 96.52« zurück. Die so genannte Zero-Width-Assertion»G« (Zeile 17) sorgt dafür, dass die Regex-Engine nicht jedes Mal zum Textanfang zurückspringt, sondern den Suchvorgang direkt hinter dem letzten Treffer fortsetzt.
Grenzlasten
Auf der Nagios-Seite ruft das Plugin in Listing 2 mit LWP::Simple das gerade vorgestellte CGI-Skript auf dem Server auf, schnappt sich die Ausgabezeile und zerlegt sie mit »split« in Felder, die es im Hash »%values« ablegt. Ist die CPU zu weniger als 50 Prozent verfügbar, meldet das Plugin den Zustand Critical, sind es weniger als 70 Prozent, spricht es nur eine Warnung aus. Gleiches gilt für die gemessenen Iowait-Werte, bei denen die jeweiligen Grenzwerte bei 10 und 20 Prozent liegen.
|
Listing 2: |
|---|
01 #!/usr/bin/perl
02 ###########################################
03 use strict;
04 use LWP::Simple;
05 use Log::Log4perl qw(:easy);
06 use Nagios::Clientstatus;
07
08 my $version = "0.01";
09 my $ncli = Nagios::Clientstatus->new(
10 help_subref =>
11 sub { print "usage: $0 urln" },
12 version => $version,
13 mandatory_args => [ "url" ],
14 );
15
16 my $url = $ncli->get_given_arg("url");
17
18 my $data = get $url;
19
20 unless($data) {
21 print "Failed to get $urln";
22 exit $ncli->exitvalue("unknown");
23 }
24
25 my %values = split ' ', $data;
26
27 my $status =
28 $values{idle} < 50 ? "critical" :
29 $values{idle} < 70 ? "warning" :
30 $values{iowait} > 20 ? "critical" :
31 $values{iowait} > 10 ? "warning" :
32 "ok";
33
34 print "IOSTAT ", uc($status), " - $datan";
35
36 exit $ncli->exitvalue($status);
|
Das Modul Nagios::Clientstatus vom CPAN erleichtert die Arbeit etwas, da es prüft, ob das Plugin alle erforderlichen Parameter erhalten hat. Außerdem versteht die Methode »exitvalue()« auch Strings wie »warning« statt des Zahlenwerts »1« aus der Nagios-Welt. Von der Kommandozeile aus mit »check_iostat -url=http://webserver.com/cgi/iostat.cgi« aufgerufen zeigt das Plugin nun folgende Ausgabe:
IOSTAT OK - user 2.99 nice 0.00 sys 0.00 iowait 0.00 idle 96.52
Nagios wird später das Plugin genauso aufrufen und sowohl den Exit-Wert interpretieren als auch den auf Stdout angegebenen Text anzeigen. Zu beachten ist allerdings, dass Nagios::Clientstatus mindestens Version 2.35 von Getopt::Long benötigt.
Plugin einbinden
Um das neue Plugin in eine existierende Nagios-Installation einzuhängen, kopiert der Admin das Skript »check_iostat« ausführbar ins Verzeichnis »/usr/local/nagios/libexec«. Die Nagios-Konfiguration erweitert er gemäß Abbildung 4 um ein Template namens »ez-service«, das später auch die Definition weiterer Plugins vereinfacht. Es ist gängige Praxis in Nagios-Konfigurationen, unter anderem Service-Templates zu definieren, die am Eintrag »register 0« erkennbar sind. Später erweitern Service-Definitionen diese Templates um spezielle Einträge.
Die Konfiguration »define service« legt in Abbildung 4 den neuen Iostat-Service an. Er bindet das vorher definierte Template mit »use ez-service« ein und übernimmt damit zahlreiche Parameter für Testabläufe, E-Mail-Benachrichtigungen und vieles mehr. Der Eintrag »notification_interval 0« verhindert zum Beispiel, dass Nagios für ein Problem mehrere Mails verschickt.
Mit »normal_check_interval« bestimmt der Admin den Zeitabstand zwischen den Service-Tests in Minuten und »max_check_attempts« legt fest, nach wie vielen fehlgeschlagenen Tests Nagios eine Benachrichtigung schickt. Die »service_notification_options« konfigurieren, bei welchen Zustandsänderungen Nagios sich meldet: Die Option »w« bedeutet Warning, »u« steht für Unknown, »c« für Critical, »r« für Recovery. Ähnliches gilt für »host_notification_options«, hier bedeutet zusätzlich »d« Down.
Wenn der Nagios-Server wegen eines Netzwerkproblems selbst von der Umwelt abgeschnitten ist, kommt natürlich auch keine Warnung per E-Mail übers Internet an. In diesem Fall erreicht den erleichterten Admin aber zumindest die Recovery-Mail, sobald das Problem behoben ist.

Abbildung 3: Das Kommando »iostat 1 2« gibt im zweiten Teil die aktuelle CPU- und Platten-Auslastung eines Servers aus.
Automatisch reagieren
Ein weiteres sehr nützliches Feature sind Event-Handler, die Aktionen definieren, die Nagios selbstständig ausführt, wenn es bestimmte Probleme erkennt. Manche Schwierigkeiten kann das System auf diese Weise aus dem Weg räumen, bevor es die Hilfe eines Admin braucht.
Ein Service ist in Nagios immer einem Host zugeordnet, den das System separat auf Verfügbarkeit testet. Die Host-Spezifikation verlangt weitere Einträge in der Konfigurationsdatei. Der Eintrag »host_name dreamhost« gibt an, dass ein solcher Host konfiguriert ist.
Der Parameter »check_command« der Service-Definition spezifiziert den Aufruf des Plugin »check_iostat«. Es wird jedoch nicht direkt aus der Service-Definition heraus aufgerufen, sondern über ein weiter oben mit »define command« konfiguriertes Kommando, das die auszuführende Kommandozeile festlegt. Die dabei übergebene URL ersetzt den Platzhalter ». Diese URL übergab der Eintrag »check_command« in der Service-Definition dem »iostat«-Kommando getrennt durch ein Ausrufezeichen.
Auch die Angabe »24×7« für die Parameter »check_period« und »notification_period« erfordert weitere Einträge, die die E-Mail des Admin und seine Verfügbarkeit definieren. Unter [1] ist dafür die Beispieldatei »eznagios.cfg« erhältlich, die sich mit »cfg_file=/usr/local/nagios/etc/eznagios.cfg« in die zentrale Konfigurationsdatei »nagios.cfg« einbinden lässt. Außerdem definiert sie weitere Nagios-Tests, die anzeigen, wie voll die Festplattenpartitionen sind oder ob der Router oder der DNS-Server des Providers noch funktionieren.
Hitzefühler
Ein weiteres Beispiel eines selbst gebauten Nagios-Plugin zeigt »check_temperature«. Das Skript (Listing 3) kontaktiert die Round-Robin-Datenbank des in [3] vorgestellten Temperaturfühlers und schlägt Alarm, falls die Außen- oder Innentemperatur sich außerhalb festgelegter Grenzen bewegen. Typisch für Nagios-Plugins akzeptiert es Kommandozeilenparameter für die Grenzwerte. Ein Aufruf von »check_temperature -warn=30 -crit=35 -dsname=Inside« löst eine Warnung aus, falls die Innentemperatur über 30 Grad Celsius steigt. Bei 35 Grad wird die Grenze zu Critical überschritten. Abbildung 5 zeigt die unterschiedlichen Exit-Werte und Ausgaben des Plugin für unterschiedliche Parameter.
|
Listing 3: |
|---|
01 #!/usr/bin/perl -w
02 ###########################################
03 use strict;
04 use RRDTool::OO;
05 use Getopt::Std;
06 use Pod::Usage;
07 use Nagios::Clientstatus;
08
09 my $N = "TEMPERATURE";
10
11 my $nc = Nagios::Clientstatus->new(
12 help_subref => sub { pod2usage() },
13 mandatory_args => [qw(
14 crit warn dsname
15 )],
16 );
17
18 my $rrd = RRDTool::OO->new(
19 file => "/tmp/temperature.rrd" );
20
21 my $dsnames = $rrd->meta_data("dsnames");
22
23 $rrd->fetch_start(
24 start => time() - 6*60,
25 end => time()
26 );
27
28 my $temp;
29
30 if(my($time, @values) =
31 $rrd->fetch_next()) {
32 for(my $i=0; $i<@$dsnames; $i++) {
33 if($dsnames->[$i] eq
34 $nc->get_given_arg("dsname")) {
35 $temp = $values[$i];
36 last;
37 }
38 }
39 }
40
41 my $status = "ok";
42
43 if(! defined $temp) {
44 $status = "unknown";
45 }
46 elsif($temp >=
47 $nc->get_given_arg("crit")) {
48 $status = "critical";
49 }
50 elsif($temp >=
51 $nc->get_given_arg("warn")) {
52 $status = "warning";
53 }
54
55 printf "$N %s - %s: %sn",
56 uc($status),
57 $nc->get_given_arg("dsname"),
58 defined $temp ?
59 sprintf("%.1f", $temp) :
60 "NODATA";
61
62 exit $nc->exitvalue($status);
|
Analog zum vorher vorgestellten Iostat-Plugin übergibt folgende Service-Konfiguration dem Skript die Parameter: »check_command check_temperature!30!30!Inside«. Der entsprechende Eintrag für »command« sieht so aus:
define command {
command_name check_temperature
command_line $USER1$/check_temperature -warn=$ARG1$ -crit=$ARG2$ -dsname=$ARG3$
}
Die bunte Tabelle in Abbildung 1 zeigt im Mittelteil, dass beide Temperaturtests sich mit 18,8 (innen) und 15,9 Grad Celsius (außen) im grünen Bereich bewegen. Die Wohnung brennt also nicht.
Die Nagios-2.0-Distribution ist auf der Projektseite [5] als Tarball verfügbar. Nach dem Auspacken führen die folgenden Schritte zu einem funktionierenden Nagios-Server.

Abbildung 5: Ausgaben und Exit-Werte des Temperatur-Plugin auf unterschiedliche Kommandozeilenparameter.
Installation
Zuerst legt man einen eigenen Benutzer und eine Gruppe für Nagios an und startet danach wie üblich »configure« und »make«:
adduser nagios cd nagios-2.0 ./configure make all
Dann sind die Binärprogramme, CGI-Skripte und HTML-Seiten zu installieren, das Startskript in »/etc/rc.d/init.d« und eine Beispiel-Konfiguration anzulegen:
make install make install-init make install-config
Ein gesonderter Tarball [2] enthält die Standard-Plugins für Nagios 2.0, die man im Zuge der Installation ins Verzeichnis »/usr/local/nagios/libexec« entpackt.
Konfigurationshürden
Die größte Hürde bei Nagios ist die Konfiguration [6]. Nach der Installation muss der Admin nicht weniger als sechs verschiedene Konfigurationsdateien erstellen. Zum Glück liegen der Nagios-Distribution Beispieldateien bei, die der Admin nur an die örtlichen Verhältnisse anzupassen braucht. Dazu benennt er einfach die in dem Verzeichnis »/usr/local/nagios/etc« liegenden Dateien mit der Endung ».cfg-sample« in ».cfg«-Dateien um.
Eine Nagios-Installation sollte auf keinen Fall aus dem Internet frei zugänglich sein. Der Installateur richtet den Nagios-Webserver mit den Einstellungen aus Abbildung 6 ein. Nach einem Start des Nagios-Daemon mit »# /etc/rc.d/init.d/nagios restart« und einem HUP-Signal an den Webserver sind unter [http://localhost/nagios] die gemessenen Daten und zudem eine Reihe von Berichten (Abbildung 2) für authentifizierte Benutzer zugänglich.
Gastzugang nur hintereiner Firewall
Läuft die Nagios-Seite hinter einer Firewall und haben nur vertrauenswürdige Personen Zugriff, dann ist der Aufwand überflüssig und es genügt, die Zeilen mit »Require valid-user« in »httpd.conf« auszukommentieren. In der Nagios-Konfigurationsdatei »cgi.cfg« gewähren in diesem Fall die Einträge aus Listing 4 einem nicht authentifizierten Gast Zugang zu allen Daten und Service-Kommandos. Einen solchen Server in das Internet zu stellen wäre extrem gefährlich, doch hinter der eigenen Firewall ist diese Einstellung ganz praktisch.
|
Listing 4: |
|---|
01 # cgi.cfg: 02 default_user_name=guest 03 04 authorized_for_system_information=nagiosadmin,guest 05 authorized_for_configuration_information=nagiosadmin,guest 06 authorized_for_all_services=nagiosadmin,guest 07 authorized_for_all_hosts=nagiosadmin,guest 08 authorized_for_all_service_commands=nagiosadmin,guest 09 authorized_for_all_host_commands=nagiosadmin,guest |
Nach allen Änderungen in Konfigurationsdateien empfiehlt es sich, zunächst zu prüfen, ob Fehler in der Konfiguration vorliegen, bevor der Admin den Daemon neu startet. Folgendes Kommando prüft die Syntax:
cd /usr/local/nagios bin/nagios -v etc/nagios.cfg
Eine gut durchdachte Überwachungsstrategie, die Nagios zuverlässig ausführt, lässt Admins ruhig schlafen – es sei denn, es schlägt Alarm. Doch selbst in diesem Fall ist ein Weckruf vom Pager dem Telefonanruf eines verärgerten Benutzers vorzuziehen. (jcb)
|
Infos |
|---|
|
[1] Listings zu diesem Artikel: [ftp://www.linux-magazin.de/pub/listings/magazin/2006/05/Perl] [2] Standard-Plugins für Nagios-2.0: [http://prdownloads.sourceforge.net/nagiosplug/nagios-plugins-1.4.2.tar.gz] [3] Michael Schilli, “Perl-Snapshot – Ist das nicht cool?”: Linux-Magazin 03/06, S. 116, [https://www.linux-magazin.de/Artikel/ausgabe/2006/03/perl/perl.html] [4] Michael Schwartzkopff, “Fernsicht – Das Simple Network Management Protocol”: Linux-Magazin 03/06, S. 54 [5] Homepage des Netzwerk-Monitors Nagios: [http://www.nagios.org] [6] Dietmar Ruzicka, “Alles im Blick”: Linux-Magazin 03/03, [https://www.linux-magazin.de/Artikel/ausgabe/2003/03/066_nagios/nagios.html] [7] Deutschsprachiges Nagios-Portal:[http://www.nagios-portal.de] [8] Entwicklerseite für Nagios-Plugins: [http://nagiosplug.sourceforge.net] |
|
Der Autor |
|---|
|
|









