Livestatus


Dieser Artikel ist noch nicht fertig und nur ein Entwurf!

1. Einleitung

Der Livestatus ist die wichtigste Schnittstelle in Check_MK. Durch sie bekommen Sie schnellstmöglich und live Zugriff auf alle Daten der überwachten Hosts und Services. So werden z. B. die Daten der Tactical Overview direkt über diese Schnittstelle abgerufen. Da diese direkt aus dem RAM geholt werden, werden langsame Festplattenzugriffe vermieden und es gibt einen schnellen Zugriff auf das Monitoring, ohne das System zu sehr zu belasten.

Um die Daten zu strukturieren, werden sie in Tabellen und Spalten geordnet. Die Tabelle hosts enthält dann z. B. die Spalten name, state und viele weitere. Jede Zeile in der Tabelle hosts repräsentiert dabei einen Host, in der Tabelle services einen Service usw. Auf diese Weise können die Daten einfach durchsucht und abgerufen werden.

Dieser Artikel soll Ihnen helfen, diese Schnittstelle für eigene Abfragen, Erweiterungen und Anpassungen zu nutzen. Alle Abfragen und Kommandos in diesem Artikel können Sie als Instanzbenutzer durch Copy&Paste direkt ausprobieren.

2. Die Livestatus Query Language (LQL)

2.1. Nutzung der LQL in der Shell

Der Zugriff zum Livestatus erfolgt über einen Unix-Socket unter Benutzung der Livestatus Query Language (LQL). Diese ist in ihrer Syntax an HTTP angelehnt.

Sie können auf der Kommandozeile auf verschiedene Arten auf die Schnittstelle zugreifen. Eine Möglichkeit ist es, über die Kommandos echo und unixcat den Befehl an den Socket zu leiten. Check_MK liefert für den Instanzbenutzer das Tool unixcat bereits mit. Wichtig: Alle Eingaben an den Socket unterscheiden Groß- und Kleinschreibung, so dass diese immer eingehalten werden muss:

OMD[mysite]:~$ echo "GET hosts\nColumns: name" | unixcat ~/tmp/run/live

Die Schnittstelle erwartet alle Befehle und Header in jeweils einer eigenen Zeile. Markieren Sie daher jeden Zeilenumbruch mit einem \n. Als Alternative zu dem Kommando oben können Sie auch den Skriptbefehl lq nutzen, welcher Ihnen einiges bei der Eingabe abnimmt:

OMD[mysite]:~$ lq "GET hosts\nColumns: name"

Oder Sie starten den interaktiven Eingabestream und geben dann den Befehl und die Header nacheinander ein. Mit einer Leerzeile führen Sie den Befehl mit seinen Headern aus und eine weitere Zeile beendet den Zugriff auf den Socket. Beachten Sie, dass in dem Beispiel alles vor der ersten Leerzeile zum dem Befehl gehört und alles zwischen der ersten und zweiten Leerzeile die Antwort ist:

OMD[mysite]:~$ lq
GET hosts
Columns: name

myserver123
myserver124
myserver125

OMD[mysite]:~$ 

Die folgenden Beispiele werden immer mit dem lq-Befehl ausgeführt; in direkter Form, wenn der Aufruf kurz ist und als Eingabestream bei einem längeren.

Befehle der LQL

In den ersten Beispielen haben Sie bereits den ersten der beiden Befehle gesehen: Mit GET können Sie alle verfügbaren Tabellen abrufen. In der Befehlsreferenz finden Sie eine vollständige Liste aller verfügbaren Tabellen mit einer Beschreibung In diesem Artikel wird die generelle Benutzung des Livestatus gezeigt.

Mit COMMAND können Sie Kommandos direkt an den Core schicken, um z. B. eine Downtime zu setzen oder Benachrichtigungen komplett zu deaktivieren. Eine Liste aller verfügbaren Kommandos finden Sie ebenfalls in der Befehlsreferenz bei den Commands.

Header in der LQL

Zu jedem GET-Befehl können Sie verschiedene Header hinzufügen, um das Ergebnis der Abfrage einzugrenzen, nur bestimmte Spalten einer Tabelle auszugeben und vieles mehr. Die beiden wichtigsten Header sind die folgenden:

Header Beschreibung
Columns Es werden nur die angegebenen Spalten einer Abfrage ausgegeben.
Filter Es werden nur die Einträge ausgegeben, auf die eine bestimmte Bedingung zutrifft.

Eine Liste aller Header mit einer Kurzbeschreibung finden Sie hier.

Verfügbare Spalten und Tabellen anzeigen

Sie werden sich nicht alle Tabellen und deren Spalten merken können und haben vielleicht auch nicht immer auf dieses Handbuch (mit den Referenzen in der Online-Version) Zugriff. Es lässt sich jedoch schnell eine Abfrage erstellen, welche die gewünschten Informationen bereit stellt. Um eine Liste aller verfügbaren Tabellen zu bekommen führen Sie die folgende Abfrage aus und entfernen in der Ausgabe die duplizierten Zeilen mit sort. In der Ausgabe sehen Sie die ersten vier Zeilen als Beispielausgabe:

OMD[mysite]:~$ lq "GET columns\nColumns: table" | sort -u
columns
commands
comments
contactgroups

Für die Abfrage aller Spalten zu einer Tabelle müssen Sie diese natürlich angeben. Ersetzen Sie daher hosts durch die gewünschte Tabelle. Auch hier sind die ersten vier Zeilen der Ausgabe als Beispiel zu sehen:

OMD[mysite]:~$ lq "GET columns\nFilter: table = hosts\nColumns: name"
accept_passive_checks
acknowledged
acknowledgement_type
action_url

2.2. Nutzung der LQL in Python

Da Check_MK sehr stark auf Python aufbaut, bieten sich Skripten in dieser Sprache an. Für den Zugriff auf den Socket des Livestatus können Sie das folgendende Skript als Ausgangsbasis nutzen:

live_example.py
#!/usr/bin/env python
# Sample program for accessing Livestatus from Python

import json, os, socket

# for local site only: file path to socket
address = "%s/tmp/run/live" % os.getenv("OMD_ROOT")
# for local/remote sites: TCP address/port for Livestatus socket
# address = ("localhost", 6557)

# connect to Livestatus
family = socket.AF_INET if type(address) == tuple else socket.AF_UNIX
sock = socket.socket(family, socket.SOCK_STREAM)
sock.connect(address)

# send our request and let Livestatus know we're done
sock.sendall("GET status\nOutputFormat: json\n")
sock.shutdown(socket.SHUT_WR)

# receive the reply as a JSON string
chunks = []
while len(chunks) == 0 or chunks[-1] != "":
    chunks.append(sock.recv(4096))
sock.close()
reply = "".join(chunks)

# print the parsed reply
print(json.loads(reply))

2.3. Nutzung der Livestatus-API

Check_MK stellt auch eine API für die Programmiersprachen Python, Perl und C++ zur Verfügung, welche den Zugriff auf den Livestatus vereinfachen. Zu jeder Sprache steht Ihnen Beispielcode zur Verfügung, welcher die Nutzung erläutert. Die Pfade zu diesen Beispielen finden Sie in dem Kapitel Dateien und Verzeichnisse.

3. Einfache Abfragen

3.1. Spalten abfragen (Columns)

Bisher wurden in den Beispielen alle Informationen zu allen Hosts abgefragt. In der Praxis möchten Sie aber wahrscheinlich nur bestimmte Informationen (Spalten) haben. Mit dem bereits erwähnten Header Columns können Sie die Ausgabe auf diese Spalten eingrenzen. Die einzelnen Spaltennamen werden durch ein einfaches Leerzeichen getrennt.

OMD[mysite]:~$ lq "GET hosts\nColumns: name address"
myserver123;192.168.0.42
myserver234;192.168.0.73

Wie Sie sehen, erfolgt die Trennung der einzelnen Werte einer Zeile wiederum durch ein Semikolon.

Wichtig: Wenn Sie diesen Header benutzen, werden die Kopfzeilen in der Ausgabe unterdrückt. Sie können diese aber mit dem Header ColumnHeaders der Ausgabe wieder hinzufügen.

3.2. Einfache Filter setzen (Filter)

Um die Abfrage nur auf bestimmte Zeilen einzugrenzen, können Sie Spalten auf bestimmte Inhalte filtern. Wenn Sie also nur Services mit einem bestimmten Status suchen, können Sie das durch einen Filter realisieren:

OMD[mysite]:~$ lq "GET services\nColumns: host_name description state\nFilter: state = 2"
myserver123;Filesystem /;2
myserver234;ORA MYINST Processes;2

In dem Beispiel wird nach allen Services gesucht, deren Status CRIT ist; anschließend werden der Hostname, die Servicebeschreibung und dessen Status ausgegeben. Sie können solche Filter natürlich auch kombinieren und weiter einschränken auf Services, deren Status CRIT ist und noch nicht bestätigt wurde:

OMD[mysite]:~$ lq "GET services\nColumns: host_name description state\nFilter: state = 2\nFilter: acknowledged = 0"
myserver234;Filesystem /;2

Wie Sie sehen, kann man auch nach Spalten filtern, die nicht in Columns aufgelistet sind.

Operatoren und reguläre Ausdrücke

Bisher haben Sie nur auf die Übereinstimmung von Zahlen gefiltert. Sie können das vorläufige Ergebnis einer Abfrage aber auch auf „kleiner als“ bei Zahlen oder auf Zeichenketten durchsuchen. Die Ihnen zur Verfügung stehenden Operatoren finden Sie im Kapitel Operatoren der Befehlsreferenz. Dadurch können Sie z. B. auch über reguläre Ausdrücke in den Spalten filtern:

OMD[mysite]:~$ lq "GET services\nColumns: host_name description state\nFilter: description ~~ exchange database|availability"
myserver123;Exchange Database myinst1;1
myserver123;Exchange Availability Service;0
myserver234;Exchange Database myinst3;0

Mit dem richtigen Operator können Sie auf verschiedene Art und Weise mit regulären Ausdrücken die Spalten durchsuchen. Der Livestatus wird einen solchen Ausdruck grundsätzlich immer als „kann irgendwo in der Spalte vorkommen“ interpretieren, sofern das nicht entsprechend anders definiert wurde. Auf den Anfang einer Zeile verweisen Sie z. B. mit dem Zeichen ^, während Sie mit dem Zeichen $ auf das Ende einer Zeile hinweisen. Eine ausführliche Liste aller Sonderzeichen für Reguläre Ausdrücke in Check_MK finden Sie in dem Artikel für Reguläre Ausdrücke.

4. Komplexe Abfragen

4.1. Filter für Listen

Manche Spalten einer Tabelle liefern nicht nur einen Wert zurück, sondern gleich eine ganze Liste davon. Damit Sie auch diese effektiv durchsuchen können, haben die Operatoren hier eine andere Bedeutung. Eine vollständige Liste der Operatoren finden Sie bei den Operatoren für Listen. So hat z. B. der Operator >= die Bedeutung „enthält“. Mit diesem können Sie z. B. nach einem bestimmten Kontakt suchen:

OMD[mysite]:~$ lq "GET hosts\nColumns: name address contacts\nFilter: contacts >= hhirsch"
myserver123;192.168.0.42;hhirsch,hhirsch,mfrisch
myserver234;192.168.0.73;hhirsch,wherrndorf

Wie Sie in dem Beispiel sehen, werden die Kontakte in der Spalte contacts kommasepariert aufgelistet. Dadurch lassen sie sich eindeutig von dem Beginn einer neuen Spalte unterscheiden. Eine Besonderheit stellt bei den Listen der Gleichheitsoperator dar. Er prüft, ob eine Liste leer ist:

OMD[mysite]:~$ lq "GET hosts\nColumns: name contacts\nFilter: contacts ="
myserver345;
myserver456;

4.2. Filter kombinieren

Bereits vorher wurden mehrere Filter kombiniert. Dabei erscheint es intuitiv, dass die Daten alle Filter passieren müssen, um angezeigt zu werden. Die Filter werden also mit einem logischen und verknüpft. Um bestimmte Filter mit einem logischen oder zu verknüpfen, können Sie am Ende der Filterreihe ein Or: gefolgt von einer Ganzzahl einfügen. Der Counter bestimmt, wie viele der letzten Zeilen zu einem oder zusammengefasst werden. Dadurch können Sie Gruppen bilden und diese beliebig kombinieren. Ein einfaches Beispiel ist das folgende. Hier werden zwei Filter so kombiniert, dass alle Services angezeigt werden, die entweder den Status WARN oder UNKNOWN haben:

OMD[mysite]:~$ lq
GET services
Columns: host_name description state
Filter: state = 1
Filter: state = 3
Or: 2

myserver123;Log /var/log/messages;1
myserver123;Interface 3;1
myserver234;Bonding Interface SAN;3

OMD[mysite]:~$ 

Sie können das Ergebnis einer Kombination aber auch negieren oder Gruppen wiederum zu Gruppen zusammenfassen. In dem Beispiel werden alle Services angezeigt, deren Status nicht OK ist und deren Beschreibung entweder nicht mit Filesystem anfängt oder einen anderen Status als UNKNOWN hat:

OMD[mysite]:~$ lq
GET services
Columns: host_name description state
Filter: state = 3
Filter: description ~ Filesystem
And: 2
Filter: state = 0
Or: 2
Negate:

myserver123;Log /var/log/messages;1
myserver123;Interface 3;1
myserver234;Filesystem /media;2
myserver234;Filesystem /home;2

4.3. Das Ausgabeformat festlegen

Sie können das Ausgabeformat auf zwei verschiedene Arten festgelegen. Zum einen können Sie die Separatoren der Standardausgabe neu definieren. Zum anderen kann die Ausgabe auch Python- oder JSON-konform erfolgen.

csv anpassen

Wie bereits beschrieben, können Sie die genaue Formatierung des Standardausgabeformates csv (kleingeschrieben!) anpassen und definieren, wie die einzelnen Elemente voneinander getrennt werden sollen. Check_MK kennt hier vier verschiedene Separatoren, um die Daten zu strukturieren. Nach dem Doppelpunkt geben Sie dazu die entsprecheden Standard-ASCII-Werte an, so dass der Filter wie folgt aufgebaut ist:

Separators: 10 59 44 124

Diese Trenner haben nun die folgende Bedeutung:

  1. Trenner für die Datensätze: 10 (Zeilenumbruch)
  2. Trenner für die Spalten eines Datensatzes: 59 (Semikolon)
  3. Trenner für die Elemente einer Liste: 44 (Komma)
  4. Trenner für die Elemente einer Serviceliste: 124 (Pipe)

Jeden dieser Werte können Sie anpassen, um die Ausgabe nach den eigenen Wünschen zu strukturieren. In dem folgenden Beispiel werden die einzelnen Spalten eines Datensatzes nicht mit Hilfe eines Semikolons (59), sondern mit einem Tabulator (9) getrennt:

OMD[mysite]:~$ lq
GET services
Columns: host_name description state
Filter: description ~ Filesystem
Separators: 10 9 44 124

myserver123     Filesystem /opt     0
myserver123     Filesystem /var/some/path       1
myserver123     Filesystem /home        0

Wichtig: Die Reihenfolge der Separatoren ist fest und darf daher nicht vertauscht werden.

Ausgabeformat ändern

Neben einer Ausgabe in csv kann Livestatus für Sie auch andere Formate erzeugen. Diese haben den Vorteil, dass sie sich in höheren Programmiersprachen leichter und sauberer parsen lassen. Sie können sich die Ausgabe demnach in den folgenden Formaten kodieren lassen:

Format Beschreibung
python Erzeugt die Ausgabe als Liste kompatibel zu Python 2.x. Text wird in Unicode formatiert.
python3 Erzeugt ebenso die Ausgabe als Liste und berücksichtigt dabei Änderungen in den Datentypen, wie z. B. die automatische Konvertierung von Text zu Unicode.
json Die Ausgabe wird ebenfalls als Liste zurückgegeben. Es werden dabei jedoch nur JSON-kompatible Formate verwendet.
CSV Formatiert die Ausgabe nach RFC-4180.
csv Siehe csv anpassen. Das ist das Standardformat, wenn nichts angegeben wird und an das offizielle CSV-Format angelehnt.

Verwechseln Sie das CSV-Format bitte nicht mit der csv-Ausgabe des Livestatus, welches verwendet wird, wenn kein Ausgabeformat festgelegt wurde. Eine korrekte Groß-/Kleinschreibung ist daher absolut notwendig. Für die Anpassung übergeben Sie am Ende ein OutputFormat statt desSeparator:

OMD[mysite]:~$ lq
GET services
Columns: host_name description state
Filter: description ~ Filesystem
OutputFormat: json

[["myserver123","Filesystem /opt",0]
["myserver123","Filesystem /var/some/path",1]
["myserver123","Filesystem /home",0]]

5. Statistiken abrufen (Stats)

Es wird Situationen geben, in denen Sie gar nicht daran interessiert sind, wie der Status eines einzelnen oder einer Gruppe von Services ist. Vielmehr ist die Anzahl der Services wichtig, welche gerade WARN sind oder die Anzahl der überwachten Datenbanken. Livestatus ist in der Lage mit Stats Statistiken zu erstellen und auszugeben.

Zählen

Die Tactical Overview bekommt ihre Daten, indem sie über Livestatus Statistiken zu Hosts, Services und Events abruft und dann in der Oberfläche von Check_MK darstellt. Mit dem direkten Zugriff auf Livestatus können Sie ebenfalls eigene Aufsummierungen erstellen:

OMD[mysite]:~$ lq
GET services
Stats: state = 0
Stats: state = 1
Stats: state = 2
Stats: state = 3

34506;124;54;20

Solche Statistiken lassen sich übrigens auch mit allen Filtern kombinieren.

Gruppieren

Auch Statistiken lassen sich mit and/or zusammenfassen. Die Header heißen dann StatsAnd oder StatsOr. Wenn Sie die Ausgabe umkehren wollen, benutzen Sie StatsNegate. In dem Beispiel wird die Gesamtzahl der Hosts ausgegeben (das erste Stats) und dazu die Anzahl derer, die als stale markiert wurden und sich nicht in einer Downtime befinden (Stats 2 und 3 werden mit einem logischen UND verknüpft):

OMD[mysite]:~$ lq
GET hosts
Stats: state >= 0
Stats: staleness >= 3
Stats: scheduled_downtime_depth = 0
StatsAnd: 2

734;23

Verwechseln Sie nicht die unterschiedlichen Möglichkeiten, die Ergebnisse der Filter und Statistiken zusammenzufassen. Während bei dem Header Filter alle Hosts ausgegeben werden, auf die die Bedinungen zutreffen, wird bei den Statistiken die Summe ausgegeben, wie oft die Stats-Filter zutreffen.

Minimum, Maximum, Durchschnitt etc.

Sie können auch Berechnungen an Werten durchführen und z. B. den Durchnittswert oder das Maximum ausgeben lassen. Eine vollständige Liste der möglichen Operatoren finden Sie hier.

In dem folgenden Beispiel wird die durschnittliche, minimale und maximale Zeit ausgegeben, welche die Checkplugins eines Hosts für die Berechnung eines Status benötigen:

OMD[mysite]:~$ lq
GET services
Filter: host_name = myserver123
Stats: avg execution_time
Stats: max execution_time
Stats: min execution_time

0.0107628;0.452087;0.008593

Berechnungen von Metriken werden etwas besonders behandelt. Auch hier sind alle Funktionen des Stats-Header möglich. Diese werden jedoch auf alle Metriken eines Service einzeln angewandt. Nachfolgend werden als Beispiel die Metriken der CPU-Benutzung einer Hostgruppe aufsummiert:

OMD[mysite]:~$ lq
GET services
Filter: decription ~ CPU utilization
Filter: host_groups >= cluster_a
Stats: sum perf_data

guest=0.000000 steal=0.000000 system=34.515000 user=98.209000 wait=23.008000

6. Begrenzung der Ausgabe (Limit)

Die Anzahl der Zeilen in der Ausgabe ist begrenzbar. Das kann z. B. nützlich sein, wenn Sie nur sehen wollen, ob überhaupt eine Antwort auf eine Livestatus-Anfrage zurückkommt, aber eine seitenlange Ausgabe verhindern wollen:

OMD[mysite]:~$  lq "GET hosts\nColumns: name\nLimit: 3"
myserver123
myserver234
myserver345

Beachten Sie, dass dieses Limit auch funktioniert, wenn Sie es mit anderen Headern kombinieren. Wenn Sie z. B. mit Stat zählen, wie viele Hosts den Status UP haben und die Ausgabe auf 10 begrenzen, werden nur die ersten 10 Hosts berücksichtigt.

7. Zeitbeschränkungen (Timelimit)

Sie können nicht nur die Anzahl der ausgegebenen Zeilen einschränken. Auch die maximale Zeit, wie lange eine Abfrage dauern darf, können Sie begrenzen. Damit verhindern Sie, dass eine Livestatus-Abfrage nicht für immer eine Verbindung blockiert, weil sie aus irgendwelchen Gründen hängt. Die Zeitbeschränkung gibt dabei die Zeit in Sekunden an, die die Verarbeitung einer Abfrage dauern darf:

OMD[mysite]:~$ lq "GET hosts\nTimelimit: 1"

8. Kopfzeilen aktivieren (ColumnHeaders)

Mit den ColumnHeaders können Sie zu der Ausgabe die Namen der Spalten ausgeben lassen. Diese werden normalerweise unterdrückt, um die Weiterbearbeitung zu vereinfachen:

OMD[mysite]:~$  lq "GET hosts\nColumns name address groups\nColumnHeaders: on"
name;address;groups
myserver123;192.168.0.42;cluster_a,headnode
myserver234;192.168.0.43;cluster_a
myserver345;192.168.0.44;cluster_a

9. Berechtigungen (AuthUser)

Wenn Sie Skripten auf Basis des Livestatus zur Verfügung stellen möchten, sollen die Nutzer wahrscheinlich nur die Daten sehen, für die sie auch berechtigt sind. Check_MK stellt dafür den Header AuthUser mit der Einschränkung zur Verfügung, dass dieser nicht in den folgenden Tabellen benutzt werden kann:

  • columns
  • commands
  • contacts
  • contactgroups
  • eventconsolerules
  • eventconsolestatus
  • status
  • timeperiods

Umgekehrt bedeutet es, dass Sie diesen Header in allen Tabellen nutzen können, die auf die Tabellen hosts oder services zugreifen. Ob ein Nutzer nun berechtigt ist, hängt dabei von seinen Kontaktgruppen ab.

Auf diese Weise werden bei einer Abfrage nur diejenigen Daten ausgegeben, die der Kontakt auch sehen darf. Beachten Sie hier den Unterschied zwischen strict und loose bei den Berechtigungseinstellungen:

OMD[mysite]:~$ lq "GET services\nColumns: host_name description contacts\nAuthUser: hhirsch"
myserver123;Uptime;hhirsch
myserver123;TCP Connections;hhirsch
myserver123;CPU utilization;hhrisch,kkleber
myserver123;File /etc/resolv.conf;hhirsch
myserver123;Kernel Context Switches;hhrisch,kkleber
myserver123;File /etc/passwd;hhirsch
myserver123;Filesystem /home;hhirsch
myserver123;Kernel Major Page Faults;hhrisch
myserver123;Kernel Process Creations;hhirsch
myserver123;CPU load;hhrisch,kkleber

10. Verzögerungen (Wait)

Mit den Wait-Headern erstellen Sie Abfragen, um bestimmte Datensätze zu bekommen, ohne wissen zu müssen, wann die Bedingungen für die Daten erfüllt sind. Das kann nützlich sein, wenn Sie zu einem bestimmten Fehlerbild Vergleichsdaten benötigen, aber das System nicht durchgehend sinnlos belasten wollen. Informationen werden demnach nur dann abgerufen, wenn Sie auch wirklich benötigt werden.

Eine vollständige Liste der Wait-Header finden Sie hier.

In dem folgenden Beispiel wird der Service Disk IO SUMMARY eines ESXi-Servers ausgegeben, sobald der Status des Service CPU load auf einer bestimmten VM CRIT wird. Durch den Header WaitTimeout wird die Abfrage auch dann ausgeführt, wenn sie nach 10000 Millisekunden nicht eingetreten ist. Das verhindert, dass die Livestatus-Verbindung lange blockiert wird:

OMD[mysite]:~$ lq
GET services
WaitObject: myvmserver CPU load
WaitCondition: state = 2
WaitTrigger: state
WaitTimeout: 10000
Filter: host_name = myesxserver
Filter: description = Disk IO SUMMARY
Columns: host_name description plugin_output

myesxserver;Disk IO SUMMARY;OK - Read: 48.00 kB/s, Write: 454.54 MB/s, Latency: 1.00 ms

Ein weiterer Anwendungsfall ist die Kombination mit einem Kommando. Sie können ein Kommando absetzen und die Ergebnisse abrufen, sobald diese verfügbar sind. In dem nachfolgenden Beispiel werden die aktuellen Daten eines Services abgerufen und angezeigt. Dafür wird zuerst das Kommando übergeben und danach eine normale Abfrage erstellt. Diese prüft, ob die Daten des Service Check_MK jünger sind als der definierte Zeitpunkt. Sobald die Bedingung erfüllt ist, wird der Status des Service Memory ausgegeben.

OMD[mysite]:~$ lq "COMMAND [$(date +%s)] SCHEDULE_FORCED_SVC_CHECK;myserver;Check_MK;$(date
+%s)"
OMD[mysite]:~$ lq
GET services
WaitObject: myserver Check_MK
WaitCondition: last_check >= 1517914646
WaitTrigger: check
Filter: host_name = myserver
Filter: description = Memory
Columns: host_name description state

myserver;Memory;0

Wichtig: Achten Sie darauf, dass der Zeitstempel in last_check aus dem Beispiel durch einen aktuellen ersetzt werden muss. Andernfalls ist die Bedingung immer erfüllt und die Ausgabe kommt sofort.

11. Zeitzonen (Localtime)

Viele größere Monitoringumgebungen rufen auf globaler Ebene Hosts und Services ab. Da kann es schnell zu einer Situation kommen, bei der die beteiligten Monitoringinstanzen in verschiedenen Zeitzonen arbeiten. Da Check_MK die zeitzonenunabhängige Unixzeit benutzt, sollte es hier zu keinen Problemen kommen.

Falls einer der Server jedoch einer falschen Zeitzone zugeordnet wurde, können Sie diese Differenz mit dem Header Localtime ausgleichen. Übergeben Sie dazu der Abfrage die aktuelle Zeit. Check_MK wird dann selbstständig auf die näher liegende halbe Stunde runden und die Differenz ausgleichen. Sie können die Zeit automatisch übergeben, wenn Sie eine direkte Abfrage nutzen:

OMD[mysite]:~$ lq "GET hosts\nColumns: name last_check\nFilter: name = myserver123\nLocaltime: $(date +%s)"
myserver123;1511173526

Ansonsten übergeben Sie das Ergebnis aus date +%s, wenn Sie den Eingabestream nutzen möchten:

OMD[mysite]:~$ lq
GET hosts
Columns: name last_check
Filter: name = myserver123
Localtime: 1511173390

myserver123;Memory;1511173526

12. Statuscodes (ResponseHeader)

Wenn Sie eine API schreiben, wollen Sie sehr wahrscheinlich auch einen Statuscode als Rückmeldung haben, um die Ausgabe besser verarbeiten zu können. Der Header ResponseHeader unterstützt die Werte off (Standard) und fixed16 und bietet damit eine exakt 16 Bytes lange Statusnachricht in der ersten Zeile der Antwort. Im Falle eines Fehlers enthalten die weiteren Zeilen eine ausführliche Fehlerbeschreibung zu dem Statuscode. Sie eignet sich dadurch auch gut für eine Fehlersuche in der Abfrage.

Die Statusnachricht der ersten Zeile setzt sich folgendermaßen zusammen:

  • Byte 1-3: Der Statuscode. Die komplette Tabelle der möglichen Codes finden Sie hier.
  • Byte 4: Ein einfaches Leerzeichen (ASCII-Zeichen: 32).
  • Byte 5-15: Die Länge der eigentlichen Antwort als Ganzzahl. Nicht benötigte Bytes werden mit Leerzeichen aufgefüllt.
  • Byte 16: Ein Zeilenvorschub (ASCII-Zeichen: 10).

In dem folgenden Beispiel führen Sie eine fehlerhafte Abfrage aus, indem Sie einen Filter falsch setzen bzw. mit dem Namen einer Spalte verwechseln.

OMD[mysite]:~$ lq "GET hosts\nName: myserver123\nResponseHeader: fixed16"
400          33
Coluns: undefined request header

Wichtig: Das Ausgabeformat ist im Fehlerfall immer eine Fehlermeldung in Textform. Das gilt unabhängig davon, wie Sie es angepasst haben.

13. Verbindung aufrecht erhalten (KeepAlive)

Gerade bei Skripten, welche eine Livestatus-Verbindung über das Netzwerk aufbauen, wollen Sie vielleicht den Kanal offen halten, um sich den Overhead des Verbindungsaufbaus zu sparen. Sie erreichen das mit dem Header KeepAlive und sind so in der Lage, sich einen Kanal zu reservieren. Nach einem Kommando bleibt eine Livestatus-Verbindung übrigens immer offen. Sie benötigen dafür keine Angabe eines zusätzlichen Headers.

Wichtig: Da der Kanal für die Dauer der Verbindung für andere Prozesse blockiert ist, kann das zu einem Problem werden, wenn keine Verbindungen mehr zur Verfügung stehen. Andere Prozesse müssen dann warten, bis wieder eine Verbindung frei ist. In der Standardkonfiguration hält Check_MK 20 Verbindungen bereit – erhöhen Sie bei Bedarf die maximale Anzahl dieser Verbindungen in Glodal Settings ➳ Monitoring Core ➳ Maximum concurrent Livestatus connections.

Kombinieren Sie KeepAlive immer mit dem ResponseHeader, um die einzelnen Antworten voneinander korrekt unterscheiden zu können:

OMD[mysite]:~$ lq
GET hosts
ResponseHeader: fixed16
Columns: name
KeepAlive: on

200          33
myserver123
myserver234
myserver345
GET services
ResponseHeader: fixed16
Columns: host_name description last_check
Filter: description = Memory

200          58
myserver123;Memory;1511261122
myserver234;Memory;1511261183

Achten Sie darauf, dass es zwischen der ersten Antwort und der zweiten Abfrage anders als sonst keine Leerzeile gibt. Sobald Sie in einer Abfrage den Header weglassen, wird die Verbindung nach der darauf folgenden Ausgabe durch die übliche Leerzeile geschlossen.

14. Logs abrufen

Über die Tabelle log im Livestatus haben Sie direkten Zugriff auf die Monitoringhistorie des Cores, so dass Sie mit der LQL bequem nach bestimmten Ereignissen filtern können. Verfügbarkeiten werden zum Beispiel auf Basis dieser Tabelle berechnet. Um die Übersicht zu erhöhen und eine Abfrage thematisch einzugrenzen, haben Sie auf die folgenden Log-Klassen zugriff:

Klasse Beschreibung
0 Alle Nachrichten, welche nicht über andere Klassen abgedeckt sind
1 Host- und Service-Alarme
2 Wichtige Ereignisse des Programms
3 Benachrichtigungen
4 Passive Checks
5 Externe Kommandos
6 Initiale oder aktuelle Statuseinträge (z. B. nach einer Rotation des Logs)
7 Änderungen des Programmstatus

Mit Hilfe dieser Log-Klassen können Sie bereits sehr gut eingrenzen, welche Art von Einträgen angezeigt werden soll. Zusätzlich dazu wird der Zeitraum eingeschränkt, der bei der Abfrage berücksichtigt werden soll. Das ist wichtig, da andernfalls die gesamte Historie der Instanz durchsucht wird. Das kann logischerweise das System aufgrund der Informationsflut stark ausbremsen.

Eine weitere sinnvolle Einschränkung der Ausgabe sind die Spalten (Columns), die zu einem Eintrag angezeigt werden sollen. In dem folgenden Beispiel wird nach allen Benachrichtigungen gesucht, welche in der letzten Stunde geloggt wurden:

OMD[mysite]:~$ lq "GET log\nFilter: class = 3\nFilter: time >= $(($(date +%s)-3600))\nColumns: host_name service_description time state"
myserver123;Memory;1511343365;0
myserver234;CPU load;1511343360;3
myserver123;Memory;1511343338;2
myserver234;CPU load;1511342512;0

Wichtig: Achten Sie darauf, dass Sie im interaktiven Modus des Eingabestreams keine Variablen wie in dem Beispiel nutzen können. Und schränken Sie die Abfragen immer auf einen Zeitraum ein.

Die Monitoringhistorie konfigurieren

Sie haben die Möglichkeit, die Rotation der Dateien und deren maximale Größe zu beeinflussen. Zusätzlich können Sie auch bestimmen, wie viele Zeilen einer Datei eingelesen werden sollen, bevor Check_MK abbricht. Das alles kann, abhängig von dem Aufbau der Instanz, Auswirkungen auf die Performance Ihrer Abfragen haben. Es stehen dabei die folgenden drei Parameter zur Verfügung, welche Sie in den Global Settings anpassen können:

Name Beschreibung
History log rotation: Regular interval of rotations Hier wird festgelegt, in welchem Zeitintervall die Historie in einer neuen Dadtei weitergeführt wird.
History log rotation: Rotate by size (Limit of the size) Unabhängig von dem Zeitintervall wird hier die maximale Größe einer Datei festgelegt. Die Größe stellt einen Kompromiss zwischen der möglichen Leserate und den möglichen IOs dar.
Maximum number of parsed lines per log file Nach der angegeben Anzahl an Zeilen wird eine Datei nicht weiter gelesen. Das verhindert Timeouts, falls eine Datei aus irgendwelchen Gründen doch sehr groß geworden sein sollte.

15. Verfügbarkeiten prüfen

Mit der Tabelle statehist können Sie die Rohdaten zu der Verfügbarkeit von Hosts und Services abfragen und haben somit auf alle Informationen Zugriff, die auch bei der Verfügbarkeit in der Oberfläche genutzt werden. Geben Sie auch hier immer einen Zeitraum an, da sonst alle verfügbaren Logs durchsucht werden, was das System sehr stark auslasten kann. Zusätzlich gelten folgende Besonderheiten:

  • Der Zeitraum, in der ein Host/Service einen bestimmten Status hatte, kann sowohl absolut in Unix-Zeit ausgegeben werden, als auch relativ als prozentualer Anteil zum abgefragten Zeitraum.
  • In Zeiten, in denen ein Host/Service nicht überwacht wurde, ist der Status -1.

Die Überprüfung, ob, wann und wie lange ein Host/Service überwacht wurde, ist in Check_MK durch das Logging von initialen Status möglich. Dadurch können Sie nicht nur sehen, welcher Status zu einem bestimmten Zeitpunkt bestand, sondern auch nachvollziehen ob dieser zu diesem Zeitpunkt überhaupt überwacht wurde. Wichtig: Auch bei dem Nagios-Core ist dieses Logging aktiviert. Hier können Sie es jedoch deaktivieren:

~/etc/nagios/nagios.d/logging.cfg
log_initial_states=0

In dem folgenden Beispiel sehen Sie, wie die Abfrage einer prozentualen Verteilung und absoluten Zeiten von bestimmten Status aussieht. Als Zeitraum wurden hier die letzten 24 Stunden eingestellt und die Abfrage wurde auf die Verfügbarkeit eines Service von einem bestimmten Host eingeschränkt:

OMD[mysite]:~$ lq
GET statehist
Columns: host_name service_description
Filter: time >= 1511421739
Filter: time < 1511436139
Filter: host_name = myserver123
Filter: service_description = Memory
Stats: sum duration_ok
Stats: sum duration_warning
Stats: sum duration_critical
Stats: sum duration_part_ok
Stats: sum duration_part_warning
Stats: sum duration_part_critical

myserver123;Memory;893;0;9299;0.0620139;0;0.645764

Wie Sie eine vollständige Liste der verfügbaren Spalten abrufen, wird in der Befehlsreferenz näher erläutert.

16. Variablen im Livestatus

Sie können an verschiedenen Stellen in der Check_MK-Oberfläche Variablen nutzen, um Hosts/Services kontextbasiert zuzuweisen. Einige dieser Daten sind auch über Livestatus abrufbar. Da diese Variablen auch aufgelöst werden müssen, stehen solche Spalten in einer Tabelle doppelt zur Verfügung: Einmal als wörtlicher Eintrag und einmal als Variante, in der die Variable durch den entsprechenden Wert ersetzt wurde. Ein Beispiel dafür ist die Spalte notes_url, welche eine URL mit der Variable ausgibt:

OMD[mysite]:~$ lq "GET hosts\nColumns: name notes_url"
myserver123;https://mymonitoring/heute/wiki/doku.php?id=hosts:$HOSTNAME$

Wenn Sie jedoch stattdessen die Spalte note_url_expanded abfragen, bekommen Sie den eigentlichen Wert des Makros ausgegeben:

OMD[mysite]:~$ lq "GET hosts\nColumns: name notes_url_expanded"
myserver123;https://mymonitoring/heute/wiki/doku.php?id=hosts:myserver123

17. Livestatus über das Netzwerk nutzen

17.1. Verbindung über xinetd

Um über das Netzwerk auf den Livestatus zuzugreifen, können Sie den Unix-Socket des Livestatus an einen TCP-Port binden. Auf diese Weise können Sie Skripten über das LAN ausführen und die Daten direkt dort erheben, wo sie auch verarbeitet werden sollen.

Den Zugriff über TCP aktivieren Sie bei abgeschalteter Site mit dem omd-Befehl:

OMD[mysite]:~$ omd config set LIVESTATUS_TCP on

Standardmäßig wird Check_MK dabei den verwendeten TCP-Port auf 6557 setzen. Sie können das natürlich ebenso anpassen:

OMD[mysite]:~$ omd config set LIVESTATUS_TCP_PORT 6558

Ab Version 1.5.0 können Sie auch den Zugriff über den omd-Befehl auf bestimmte IP-Adressen einschränken:

OMD[mysite]:~$ omd config set LIVESTATUS_TCP_ONLY_FROM '127.0.0.1 192.168.30.42'

In früheren Versionen können Sie die Zugriffsbeschränktung lediglich in der Konfiguratonsdatei selbst setzen:

~/etc/mk-livestatus/xinetd.conf
service livestatus
{
        type            = UNLISTED
        socket_type     = stream
        protocol        = tcp
        wait            = no

        # limit to 100 connections per second. Disable 3 secs if above.
        cps             = 100 3

        # set the number of maximum allowed parallel instances of unixcat.
        # Please make sure that this values is at least as high as
        # the number of threads defined with num_client_threads in
        # etc/mk-livestatus/nagios.cfg
        instances       = 500

        # limit the maximum number of simultaneous connections from
        # one source IP address
        per_source      = 250

        # Disable TCP delay, makes connection more responsive
        flags           = NODELAY
# configure the IP address(es) of your Nagios server here:
        only_from       = 127.0.0.1 192.168.30.42

# ----------------------------------------------------------
# These parameters are handled and affected by OMD
# Do not change anything beyond this point.

# Disabling is done via omd config set LIVESTATUS_TCP [on/off].
# Do not change this:
        disable         = no

# TCP port number. Can be configure via LIVESTATUS_TCP_PORT
        port            = 6557

# Paths and users. Manual changes here will break some omd
# commands such as 'cp', 'mv' and 'update'. Do not toutch!
        user            = mysite
        server          = /omd/sites/mysite/bin/unixcat
        server_args     = /omd/sites/mysite/tmp/run/live
# ----------------------------------------------------------
}

Wichtig: Passen Sie nur die Option only_from manuell an. Und diese auch nur dann, wenn Sie Check_MK in der Version 1.4.0 oder älter einsetzen.

17.2. Verbindung über SSH

Spätestens, wenn Sie sich aus Ihrem lokalen Netzwerk herausbewegen, reicht die Absicherung über Xinetd nicht mehr aus, da Sie über diesen zwar die authorisierten Server bestimmen können, die Daten jedoch weiterhin im Klartext gesendet und empfangen werden. Da Livestatus bisher noch keine Authentifizierungs- oder Verschlüsselungsmethoden kennt, muss die Verbindung selbst abgesichert werden. Mit ssh können Sie genau das erreichen:

root@linux# ssh mysite@myserver 'lq "GET hosts\nColumns: name"'
myserver123
myserver234

Selbstverständlich funktioniert so auch die bekannte interaktive Eingabe.

18. Kommandos setzen

Sie können Livestatus nicht nur für die Abfrage von Daten nutzen, sondern auch, um Kommandos live und direkt an den Core (CMC oder Nagios) zu schicken. Ein korrektes Kommando enthält immer einen Zeitstempel. Dieser kann zwar beliebig sein. Da er aber in den Logs dazu benutzt wird, den Zeitpunkt der Ausführung nachzuvollziehen, ist es sinnvoll, möglichst die exakte Zeit anzugeben. Kommandos mit fehlendem Zeitstempel werden ohne Fehlermeldung und lediglich mit einem Eintrag im cmc.log verworfen!

Damit der Zeitstempel so genau, wie möglich ist, bietet es sich an, das Kommando nicht über den Eingabestream zu setzen, sondern direkt zu übergeben. Sie haben in diesem Fall auch Zugriff auf Variablen und können automatisch die gerade aktuelle Zeit übergeben:

OMD[mysite]:~$ lq "COMMAND [$(date +%s)] DISABLE_NOTIFICATIONS"

Dieses Format funktioniert sowohl mit dem Nagios-Core der  Check_MK Raw Edition, als auch mit dem CMC der  Check_MK Enterprise Edition. Allerding überschneiden sich bei den beiden Cores nur teilweise die Kommandos. Eine der Liste Kommandos für den Nagios-Core finden Sie direkt auf der Internetseite von Nagios. Für den CMC finden Sie die verfügbaren Kommandos in der Befehlsreferenz.

Besonderheiten bei Nagios

In der Liste der Kommandos werden Sie die Syntax in der folgenden Form vorfinden:

#!/bin/sh
# This is a sample shell script showing how you can submit the CHANGE_CUSTOM_HOST_VAR command
# to Nagios.  Adjust variables to fit your environment as necessary.

now=`date +%s`
commandfile='/usr/local/nagios/var/rw/nagios.cmd'

/bin/printf "[%lu] CHANGE_CUSTOM_HOST_VAR;host1;_SOMEVAR;SOMEVALUE\n" $now > $commandfile

Wie Sie gelernt haben, benutzt Check_MK ein sehr viel einfacheres Format für die Übergabe des Kommandos. Um dieses Format für Check_MK kompatibel zu übetragen, benötigen Sie lediglich das Kommando, den Zeitstempel und gegebenenfalls die Variablen:

OMD[mysite]:~$ lq "COMMAND [$(date +%s)] CHANGE_CUSTOM_HOST_VAR;host1;_SOMEVAR;SOMEVALUE"

19. Dateien und Verzeichnisse

Pfad Bedeutung
tmp/run/live Der Unix-Socket zur Übergabe der Abfragen und Kommandos.
bin/lq Skriptbefehl für die einfachere Übergabe der Abfragen und Kommandos and den Unix-Socket des Livestatus.
var/log/cmc.log Die Logdatei des CMC, in der unter anderem die Abfragen/Kommandos dokumentiert werden.
var/check_mk/core/history Die Logdatei des CMC, in der alle zur Laufzeit des Core auftretenden Änderungen eingetragen werden, wie z. B. Statusänderungen eines Host/Service.
var/check_mk/core/archive/ Hier werden die history-Logdateien archiviert. Diese werden nur nach Bedarf eingelesen.
var/log/nagios.log Die Logdatei des Nagios-Core, in der unter anderem die Abfragen/Kommandos dokumentiert werden.
var/nagios/archive/ Hier werden die history-Logdateien archiviert. Diese werden nur nach Bedarf eingelesen.
share/doc/check_mk/livestatus/LQL-examples/ In diesem Verzeichnis finden Sie einige Beispiele zu Livestatusabfragen, die Sie ausprobieren können. Die Beispiele werden an den Skriptbefehl lq geleitet, wie z. B.: lq < 1.lql
share/doc/check_mk/livestatus/api/python In diesem Verzeichnis finden Sie die API zu Python sowie einige Beispiele. Lesen Sie auch das README in diesem Verzeichnis.
share/doc/check_mk/livestatus/api/perl Die API zu Perl finden Sie hier. Auch hier gibt es wieder ein README. Die Beispiele zur Nutzung befinden sich hier in dem Unterverzeichnis examples.
share/doc/check_mk/livestatus/api/c++ Zu der Programmiersprache C++ finden Sie hier ebenfalls Beispielcode. Der Code zu der API selbst liegt ebenfalls unkompiliert vor, so dass Sie maximalen Einblick in die Funktionsweise der API haben.