Wer Infrastruktur- oder Application-Monitoring betreibt, will im Kern drei Dinge: einen schnellen, skalierbaren Core, der Checks ausführt, Statuswechsel verarbeitet und Notifications verschickt. Eine Sammlung von Check-Plugins. Ein Werkzeug zur Visualisierung der Performance-Daten. Dieser Beitrag handelt vom mittleren Stück und davon, warum und wie wir die Linuxfabrik Monitoring Plugins gebaut haben.
Den ersten Punkt löst Icinga. Den dritten typischerweise Grafana auf einer Zeitreihen-Datenbank wie InfluxDB oder Prometheus.
Der mittlere Punkt ist in der Praxis schwierig und aufwändig. Das Icinga-Projekt liefert ab Werk keine Check-Plugins mit, daher greifen viele zur klassischen Sammlung Monitoring Plugins (früher Nagios Plugins). Das hat Konsequenzen.
Wenn man sich einen minimalen Linux-Server vorstellt, sind das die Metriken, die für höhere Uptime und einfacheres Troubleshooting wirklich helfen:
ESTABLISHED, CLOSE_WAIT, TIME_WAIT, ...).Von den oben genannten Metriken bekommt man ab Werk vielleicht zwei: freien Speicher auf Mounts und irgendeine Form von Netzwerk-Latenz. Daneben jede Menge Plugins für Nischen wie Signal-Stärke spezieller WLAN-Geräte, Game-Server oder Novell NetWare.
Wer genauer hinschaut, sieht: Die Plugins sind in drei verschiedenen Sprachen geschrieben (C, Shell, Perl), unterschiedlich alt, unterschiedlich gepflegt, und sie unterscheiden sich in Parametern, Verhalten und Output. Die Abhängigkeiten der vollständigen Sammlung sind nicht trivial: auf einer schlanken Basis-Installation kann das Plugin-Paket umfangreicher sein als der Icinga-Core selbst.
Ausserhalb der klassischen Sammlung wird's nicht besser. Im Datacenter-Umfeld gibt es Tausende One-Shot-Plugins, die vor Jahren mit sehr spezifischen Feature-Sets veröffentlicht wurden, oft ohne sauberes Error-Handling, dazu in noch mehr Sprachen (Ruby, Go), was wiederum zusätzliche Abhängigkeiten bedeutet.
Nach Jahren mit Patches und selbstgeschriebenen Plugins haben wir eine neue Sammlung von Grund auf gebaut, mit ein paar Grundregeln:
WARN: etwas muss getan werden, kein Grund für einen Herzinfarkt.CRIT: nur dort, wo jemand nachts aufstehen und sofort reagieren muss.Bevor wir das Projekt gestartet haben, haben wir die Design-Regeln festgehalten:
Gemeinsame Funktionen liegen in unserer eigenen Python-Library, die von den Plugins benutzt wird.
Oft wird noch das alte check_ping zur Lebenszeichen-Prüfung von Hosts benutzt. Das Plugin ist jedoch stark limitiert. Weil andere Services und nachgelagerte Hosts vom Host-Status abhängen, muss ein Ping-Plugin zuverlässig und tolerant sein. Unser ping ist genau das:
OK.Unser ping-Plugin ist zudem schnell: es schickt im Default fünf Pings innerhalb einer Sekunde, was zu der kürzesten Laufzeit unter den von uns gemessenen Ping-Checks führt.
Stellt man sich einen CPU-Usage-Check vor, der 100 % meldet (CRIT), dann 20 % (OK), dann 90 % (CRIT), bekommt man ohne Zeit-Fenster permanentes Flapping, und niemand vertraut den Status-Wechseln mehr. Besser: erst alarmieren, wenn die Schwelle eine konfigurierbare Zeit lang überschritten war, vergleichbar mit Prometheus' for: 5m. Umgesetzt beispielsweise in cpu-usage, disk-io, network-io, procs, docker-stats, podman-stats, php-fpm-status sowie in plattformspezifischen Varianten wie fortios-cpu-usage, fortios-network-io, fortios-ha-stats und qts-cpu-usage.
Bevor wir ein neues Plugin schreiben, schauen wir auf die bestehenden Monitoring Plugins, auf existierende Tools, die den Job heute schon machen, oder direkt auf den Linux-Kernel, und übertragen die Ideen in das Monitoring-Plugins-Projekt. Beispiele:
Manchmal will man über etwas informiert werden, ohne dass es ein echter Fehler ist, etwa über ein neues GitHub-Release oder einen Security-Hinweis. Nagios und Icinga kennen keinen NOTICE-State, also simulieren wir ihn:
WARN.acknowledged liefert das Plugin wieder OK, bis sich der Befund ändert.Umgesetzt beispielsweise in feed, journald-query, logfile und librenms-alerts.
Wenn man lokal installierte Software gegen externe Quellen vergleicht (GitHub-Releases, Hersteller-Channels), gehört es zum guten Ton, diese Quellen nicht jede Minute abzufragen. Selbst wenn der Check minütlich läuft, muss er einen lokalen Cache nutzen, um den externen Traffic zu minimieren. Umgesetzt beispielsweise in matomo-version, nextcloud-version (verwendet die offiziellen Nextcloud-Update-Channels statt GitHub) und rocketchat-version.
Das Plugin systemd-unit ersetzt eine Reihe von Legacy-Plugins für Services, Sockets, Mounts, Geräte, Timer und Scopes. Einige der Fragen, die das Plugin beantwortet:
--machine)?--user)?Plugins, die helfen, die Quelle zu finden, statt nur zu signalisieren, dass es ein Problem gibt:
--top die n grössten nach CPU-Zeit oder Memory; --lengthy ergänzt die Tabelle um alle plattformspezifischen memory_info()-Felder.err und filtert bekannte Hardware-Geräusche heraus.Die Plugins laufen auf jeder Plattform mit Python 3.9+ (Linux, Windows, macOS, FreeBSD). Für Windows liefern wir zusätzlich vorkompilierte Binaries aus, sodass auf dem Zielsystem keine Python-Installation nötig ist.
main automatisch gebaut und deployed.Beim Update immer ein offizielles Release verwenden.
Ein paar Konventionen halten die Plugins konsistent:
ruff format.pylint läuft ohne --disable-Flags: der Code soll den vollständigen Linter erfüllen, nicht nur eine kuratierte Teilmenge.Die Details stehen in den Contributing Guidelines.
Brauchst du Unterstützung beim Aufbau oder Betrieb deines Icinga-Monitorings? Schau dir doch mal unsere Icinga Subscriptions und Service & Support-Modelle an und melde dich bei uns.