Mit diesem Plugin ist es möglich, Logdateien auf bestimmte Muster zu untersuchen.
check_logfiles [-t timeout] -f <konfigdatei>
Die Möglichkeiten der traditionellen Logfile-Plugins (u.a. check_log und check_log2 aus den offiziellen Nagios-Plugins) sind völlig unzureichend für den Einsatz in einem unternehmenskritischen Umfeld. check_logfiles entstand, weil diese Mängel das Aus für die Ablösung eines proprietären Systems durch Nagios bedeutet hätten.
Logfiles werden i.d.R jede Nacht oder bei Erreichen einer bestimmten Größe umbenannt und komprimiert. Je nach Betriebssystem und Unternehmen kommen dabei unterschiedliche Namensgebungen zum Einsatz. Findet diese Rotation zwischen zwei Läufen von check_logfiles statt, dann muss zur Vermeidung von Überwachungslücken auch die wegrotierte Logdatei untersucht werden. Die Rotation zu erkennen, die nun umbenannte Logdatei zu finden und eventuell seit dem letzten Lauf von check_logfiles hineingeschriebene Meldungen zu durchsuchen ist das wichtigste Feature. Häufig vorkommende Rotationsstrategien sind vordefiniert, es können aber auch unternehmensspezifische Strategien (kurz: wohin und unter welchem neuen Namen wird eine Logdatei weggeschrieben) konfiguriert werden.
Nagios Plugins liefern zunächst nur einen Exitcode und eine Zeile Text, welche das Resultat des Checks zusammenfasst. Es kann aber auch wünschenswert sein, bereits zur Laufzeit des Plugins bei jedem gefundenen Muster eine Aktion auszulösen, sprich ein Script zu starten. check_logfiles bietet diese Möglichkeit.
Wenn ein Muster gefunden wurde, dann kann es durchaus sein, daß es sich bei der entsprechenden Zeile im Logfile um einen ganz speziellen Fall handelt, der nicht als Fehler gezählt werden soll. Da es umständlich bis unmöglich ist, solche Ausnahmen in einem regulären Ausdruck zu formulieren, kann man zu allgemeinen Mustern spezielle Ausnahmen definieren, die einen zunächst eingeleiteten Alarm wieder rückgängig machen.
Die regulären Ausdrücke, nach denen gesucht werden soll, können mittels Macros einfacher gestaltet werden. Da es Macros u.a. für aktuelle Datums- und Zeitangaben gibt, ist es auch möglich, zeitlich sich ändernde reguläre Ausdrücke zu formulieren. Macros können auch in den Dateinamen von Logdateien enthalten sein.
Die Konfigurationsdatei von check_logfiles ist im Grunde eine Perl-Datei, welche eingelesen und interpretiert wird. Die in ihr enthaltenen Variablen bestimmen die Arbeitsweise von check_logfiles.
| $seekfilesdir | Ein Verzeichnis, in dem Statusdateien nach einem Lauf von check_logfiles geschrieben werden. Diese Dateien enthalten Informationen darüber, bis zu welcher Zeile eine Logdatei gelesen und untersucht wurde. Beim nächsten Lauf von check_logfiles sorgen diese Informationen dafür, daß nur die neu hinzugekommenen Zeilen in der Logdatei analysiert werden. Die Defaulteinstellung ist /tmp oder das Verzeichnis, welches bei ./configure mit –with-seekfiles-dir angegeben wurde. | |
| $protocolsdir | Ein Verzeichnis, in dem check_logfiles bei jedem Lauf die gefundenen Zeilen in eine Protokolldatei schreibt (sofern dieses gewünscht ist). Die Defaulteinstellung ist /tmp oder das Verzeichnis, welches bei ./configure mit –with-protocol-dir angegeben wurde. | |
| $protocolretention | Die Anzahl der Tage, die die maximale Lebensdauer einer Protokolldatei ausdrücken. Nach Verstreichen dieser Tage wird die Datei autom. gelöscht. Die Defaulteinstellung ist 7 Tage. | |
| $scriptpath | Eine Liste von Verzeichnissen (getrennt durch Doppelpunkt), in denen Scripts liegen, welche beim Auffinden bestimmter Muster in der Logdatei ausgeführt werden (sofern dies gewünscht ist). Die Defaulteinstellung ist /bin:/usr/bin:/sbin:/usr/sbin oder das Verzeichnis, welches bei ./configure mit –with-trusted-path angegeben wurde. | |
| $MACROS | Ein Hash, in dem eigene Macrodefinitionen eingetragen werden. | |
| Außer den selbstdefinierten Macros stehen noch weitere zur Verfügung: | ||
| $CL_HOSTNAME$ | Der Hostname ohne Domainanteil. | |
| $CL_IPADDRESS$ | Die IP-Adresse desselben. | |
| $CL_DATE_YYYY$ | Das aktuelle Jahr (1970…) | |
| $CL_DATE_MM$ | Der aktuelle Monat (01..12) | |
| $CL_DATE_DD$ | Der aktuelle Tag im Monat (01..31) | |
| $CL_DATE_HH$ | Die aktuelle Stunde (00..23) | |
| $CL_DATE_MI$ | Die aktuelle Minute (00..59) | |
| $CL_DATE_SS$ | Die aktuelle Sekunde (00..59) | |
| $CL_SERVICEDESC$ | Die Servicebeschreibung abgeleitet aus dem Namen der Konfigdatei. | |
| $CL_NSCA_SERVICEDESC$ | dto. | |
| $CL_NSCA_HOST_ADDRESS$ | Die lokale Adresse 127.0.0.1 | |
| $CL_NSCA_PORT$ | 5667 | |
| $CL_NSCA_TO_SEC$ | 10 | |
| $CL_NSCA_CONFIG_FILE$ | send_nsca.cfg | |
| Des weiteren gibt es noch Macros, die ihren Wert während eines Laufs von check_logfiles ändern: | ||
| $CL_LOGFILE$ | Das Logfile, welches momentan durchsucht wird. | |
| $CL_TAG$ | Der Tag der momentan ausgeführten Regel. | |
| $CL_SERVICESTATEID$ | Der Status des letzten Treffers (Warnung, Critical,..) | |
| $CL_SERVICEOUTPUT$ | Die zuletzt gefundene Zeile, die mit einem der Patterns übereinstimmt. | |
| Die Macros $CL_LOGFILE$, $CL_TAG$, $CL_SERVICESTATEID$, $CL_SERVICEOUTPUT$ und $CL_HOSTNAME$ stehen in allen Scripts, die aus check_logfiles heraus aufgerufen werden, auch als Environmentvariablen zur Verfügung, wobei das „CL“ durch „CHECK_LOGFILES“ ersetzt wird. (echo $CHEC_LOGFILES_LOGFILE) | ||
| @searches | Ein Array (hiess früher @logs), das einen oder mehrere Einträge besitzt, welche die eigentliche Aufgabe von check_logfiles beschreiben, nämlich: | |
| Wo wird gesucht? | ||
|---|---|---|
| tag | Ein eindeutiger Bezeichner | |
| logfile | Der Name der Logdatei, die durchsucht werden soll | |
| archivedir | Das Verzeichnis, in welchem sich die wegrotierten Logfiles befinden | |
| rotation | Eine der vordefinierten Methoden oder ein regulärer Ausdruck, mit deren Hilfe in archivedir die rotierten Logfiles identifizieren lassen | |
| Wonach wird gesucht? | ||
| criticalpatterns | Ein regulärer Ausdruck oder ein Array regulärer Ausdrücke. Passt ein solcher Ausdruck zu einer Zeile in der Logdatei, dann wird dies als Critical Event betrachtet. Wenn dem Ausdruck ein “!“ vorangestellt wurde, dann kehrt sich die Bedeutung um. Es wird dann ein Critical Event erzeugt, wenn keine Zeile im Logfile gefunden wurde, die zu diesem Pattern passt. | |
| criticalexceptions | Ein oder mehrere reguläre Ausdrücke, welche im soeben erwähnten Fall den Event wieder in einen OK Event verwandeln. Dient z.b. dazu, um Sonderfälle abzufangen. | |
| criticalthreshold | ||
| warningpatterns | Entspricht criticalpatterns, nur daß in diesem Fall ein Warning Event erzeugt wird. | |
| warningexceptions | s.o. | |
| warningthreshold | s.o. | |
| Was passiert, wenn es gefunden wurde? | ||
| script | Bei einem Treffer kann ein Script ausgeführt werden, wenn dies gewünscht ist. Es muß sich in einem der Verzeichnisse befinden, welche mit $scriptpath angegeben wurden. Die relevante Information wird per Environmentvariablen an das Script übergeben.<br>$CHECK_LOGFILES_LOGFILE - Das momentan durchsuchte Logfile <br>$CHECK_LOGFILES_TAG - Der Bezeichner des aktuellen @logs-Elements <br>$CHECK_LOGFILES_SERVICESTATE - WARNING oder CRITICAL <br>$CHECK_LOGFILES_SERVICESTATEID - 1 oder 2 <br>$CHECK_LOGFILES_HOSTNAME - Der lokale Hostname |
|
| scriptparams | Optional können an ein Script auch Kommandozeilenparameter übergeben werden. Diese können auch Macros enthalten. z.b. scriptparams ⇒ '-H $CL_NSCA_HOST_ADDRESS$'; | |
| scriptstdin | Wenn das Script Eingabe von Stdin erwartet, so kann man hier den entsprechenden String beschreiben. Er kann wiederum macros enthalten. z.b. scriptstdin ⇒ '$CL_HOSTNAME$\t$CL_SERVICEDESC$\t$CL_SERVICESTATEID$\n'; | |
| scriptdelay | Nachdem das Script beendet ist, wird eine Pause von <delay> Sekunden eingelegt, bevor check_logfiles seiene Arbeit wieder aufnimmt. | |
| Welche Optionen gibt es noch? | ||
| options | Hier kann ein String mit kommaseparierten Optionen angegeben werden. Jede Option kann mit „no“ beginnen und somit das Abschalten der entsprechenden Funktionalität bewirken.<br>[no]script - Steuert, ob der script-Befehl ausgeführt wird. <br>[no]protocol - Steuert, ob die Treffer in einer eigenen Datei zur späteren Auswertung gespeichert werden. <br>[no]count - Steuert, ob Treffer gezählt werden und in den Exitcode einfliessen. Wenn nicht, kann check_logfiles auch nur zum Ausführen von Scripts benutzt werden. <br>[no]syslogserver - Wird gesetzt, wenn in das Logfile auch Meldungen anderer Server einfließen. Mit syslogserver werden nur solche Zeilen betrachtet, die mit einem der Hostnamen des lokalen Hosts beginnen.<br>[super]smartscript - Mit dieser Option werden der Exitcode und die Ausgabe von $script wie ein (zusätzlicher) Treffer in der durchsuchten Datei behandelt. Die Angabe supersmartscript sorgt dafür, daß der Treffer, der das Script ausgelöst hat, durch Ausgabe und Exitcode desselben überschrieben wird. Endet das Script in diesem Fall mit dem Exitcode 0, dann wird der Treffer dadurch annuliert. |
|
| $prescript | Ein Script, welches in der Startphase von check_logfiles aufgerufen wird. Es hat noch nichts mit der späteren Suche nach Mustern zu tun, kann aber z.b. verwendet werden, um eine Applikation zum Leeren ihres Logbuffers zu zwingen. Der Macro $CL_TAG erhält den Wert „startup“. $prescriptparams, $prescriptstdin und $prescriptdelay können analog $scriptparams, $scriptstdin und $scriptdelay verwendet werden. | |
| $postscript | Ein Script, welches zum Abschluß von check_logfiles aufgerufen wird. Es kann verwendet werden, um das Gesamtergebnis des Laufs zu verarbeiten, wenn bei vielen zu erwartenden Treffern keine Einzelverarbeitung gewünscht wird. Der Macro $CL_TAG erhält den Wert „summary“. $postscriptparams, $postscriptstdin und $postscriptdelay können analog $scriptparams, $scriptstdin und $scriptdelay verwendet werden. | |
@logs = (
{
tag => 'san',
logfile => '/var/adm/messages',
criticalpatterns => [
'Link Down Event received',
'Loop OFFLINE',
'fctl:.*disappeared from fabric',
'.*Lun.*disappeared.*'
],
});
$scriptpath = '/usr/bin/nagios/libexec:/usr/local/nagios/contrib';
$MACROS = {
NAGIOS_HOSTNAME => "orschgeign.muc",
CL_NSCA_HOST_ADDRESS => "lpmon1.muc",
CL_NSCA_PORT => 5778
};
$postscript = 'send_nsca';
$postscriptparams = '-H $CL_NSCA_HOST_ADDRESS$ -p $CL_NSCA_PORT$ -to $CL_NSCA_TO_SEC$ -c $CL_NSCA_CONFIG_FILE$';
$postscriptstdin = '$CL_HOSTNAME$\t$CL_SERVICEDESC$\t$CL_SERVICESTATEID$\t$CL_SERVICEOUTPUT$\n';
@logs = (
{
tag => 'san',
logfile => '/var/adm/messages',
criticalpatterns => [
'Link Down Event received',
'Loop OFFLINE',
'fctl:.*disappeared from fabric',
'.*Lun.*disappeared.*'
],
},
);
$scriptpath = '/usr/bin/nagios/libexec:/usr/local/nagios/contrib';
$MACROS = {
NAGIOS_HOSTNAME => "orschgeign.muc",
CL_NSCA_HOST_ADDRESS => "lpmon1.muc",
CL_NSCA_PORT => 5778
};
@logs = (
{
tag => 'san',
logfile => '/var/adm/messages',
criticalpatterns => [
'Link Down Event received',
'Loop OFFLINE',
'fctl:.*disappeared from fabric',
'.*Lun.*disappeared.*'
],
script = 'send_nsca',
scriptparams = '-H $CL_NSCA_HOST_ADDRESS$ -p $CL_NSCA_PORT$ -to $CL_NSCA_TO_SEC$ -c $CL_NSCA_CONFIG_FILE$',
scriptstdin = '$CL_HOSTNAME$\t$CL_SERVICEDESC$\t$CL_SERVICESTATEID$\t$CL_SERVICEOUTPUT$\n',
},
);
$scriptpath = '/usr/bin';
@logs = (
{
tag => 'syslogworks',
logfile => '/var/adm/syslog/syslog.log',
rotation => 'bmwhpux',
criticalpatterns => ['!nagios:\s+braver\s+syslog'],
options => 'count,script',
script => 'send_nsca',
scriptparams => '-H $CL_NSCA_HOST_ADDRESS$ -p $CL_NSCA_PORT$ -to $CL_NSCA_TO
_SEC$ -c $CL_NSCA_CONFIG_FILE$',
scriptstdin => '$CL_HOSTNAME$\t$CL_SERVICEDESC$\t$CL_SERVICESTATEID$\tsyslog
is not working\n',
},
);
$postscript = 'logger';
$postscriptparams = '-t nagios';
$postscriptstdin = 'braver syslog ($CL_DATE_YYYY$-$CL_DATE_MM$-$CL_DATE_DD$ $CL_
DATE_HH$:$CL_DATE_MI$:$CL_DATE_SS$)';
So könnte es aussehen, wenn man check_logfiles mittels eines Cronjobs laufen lässt und nur im Fehlerfall einen Alarm per NSCA bekommen will. Bei Aufruf durch Nagios bzw. NRPE kann man sich die $script-Einträge beim Tag syslogworks sparen. Das Ganze funktioniert so, daß es einen Critical gibt, wenn der String 'nagios: braver syslog*' nicht im Logfile gefunden wird. Der sollte da aber drinstehen, weil er am Ende des letzten Laufs von check_logfiles mit dem logger-Befehl an Syslog geschickt wurde. Als Variante kann man den logger-Befehl auch im Rahmen eines prescripts ausführen. Allerdings wird unmittelbar danach bereits das Logfile nach dem String durchsucht. Ich würde auf belasteten Systemen nicht davon ausgehen, daß die Meldung in dieser kurzen Zeit vom syslogd bereits in das Logfile geschrieben wurde. Evt. kann man aber ein Wrapperscript um den logger-Befehl bauen, in dem noch ein sleep 5 ausgeführt wird. Die Methode mit NSCA benötigt mind. Version 1.3.6
$scriptpath = '/usr/bin';
$prescript = 'logger';
$prescriptparams = '-t nagios';
$prescriptstdin = 'braver syslog ($CL_DATE_YYYY$-$CL_DATE_MM$-$CL_DATE_DD$ $CL_
DATE_HH$:$CL_DATE_MI$:$CL_DATE_SS$)';
$prescriptsleep = 5;
@logs = (
{
tag => 'syslogworks',
logfile => '/var/adm/syslog/syslog.log',
rotation => 'bmwhpux',
criticalpatterns => ['!nagios:\s+braver\s+syslog'],
options => 'count',
},
);
Damit kann ein aktiver Check implementiert werden, der einfach prüft, ob es innerhalb von 5 Sekunden möglich ist, einen String an Syslog zu schicken und in der entsprechenden Logdatei wiederzufinden. Die Methode benötigt wegen des $prescriptsleep Parameters mind. Version 1.3.6.1