Icinga Web 2 und graphite
- Installation der Pakete
- Icinga2 und carbon-cache verheiraten
- graphite-web
- icinga2-module-graphite
- graphite und Nagvis
Nachdem pnp4nagios
schon schön seinen Dienst tut, aktiviere ich zusätzlich die Erstellung von Graphen über `graphite; beides wird eine Weile parallel laufen, das liefert uns eine gute Basis für die Entscheidung, was schlussendlich produktiv gehen soll. Doch Obacht: die Maschine muss hier wirklich Performance bieten, beides parallel erzeugt schon eine wahnsinnige Rechenlast.
Installation der Pakete
Im ersten Schritt werden alle benötigten Pakete installiert; für den RaspberryPi 2 gibt es das Paket graphite-web
nicht, das muss von Hand eingepfriemelt werden. Ist aber, wie du gleich sehen wirst, auch keine Hexerei. Also: auf RaspPi das Paket einfach weglassen und den Rest wie gehabt installieren. Ob ich übrigens dem Vorgängermodell des RaspPi dieses Setup würde zumuten wollen – ich bin nicht sicher…
$ apt-get install graphite-carbon libapache2-mod-wsgi python-django \
python-django-tagging python-cairo python-tz python-pyparsing \
python-memcache python-rrdtool graphite-web
Icinga2 und carbon-cache verheiraten
Jetzt weisen wir Icinga 2 an, entsprechende Daten bereitzustellen; das geschieht, wir kennen es ja bereits, über einen simplen Aufruf auf Konsole:
$ icinga2 feature enable graphite
Enabling feature graphite. Make sure to restart Icinga 2 for these changes to take effect.
$ service icinga2 restart
...
[2015-10-17 12:01:21 +0200] critical/GraphiteWriter: Can't connect to Graphite on host '127.0.0.1' port '2003'.
[2015-10-17 12:01:31 +0200] critical/TcpSocket: Invalid socket: Connection refused
Unser eben installierter carbon-cache
läuft noch nicht auf Port 2003, und Icinga 2 meckert an, dass es sich verbinden kann; also sorgen wir dafür, dass der Dienst auch beim Booten gestartet wird (indem wir das Flag auf true setzen) und starten beide durch:
## file: "/etc/default/graphite-carbon"
[...]
CARBON_CACHE_ENABLED=true
[...]
$ service carbon-cache start
[...] Restarting Graphite backend daemon: carbon-cacheStarting carbon-cache (instance a)
. ok
$ service icinga2 restart
Funktioniert alles? Wenn ja, so taucht nach einer Weile in /var/lib/graphite/whisper/
ein Ordner icinga
auf; wie immer geben die Log-Files Aufschluss darüber, wenn etwas nicht wie erwartet funktioniert. Liegen an dieser Stelle Daten bereit, können sie aufbereitet und dargestellt werden – und hier kommt nun graphite-web
ins Spiel.
graphite-web
Charmant, um konkrete Werte zu vergleichen und sich Graphen nach Wunsch zusammenzustellen – ein sehr bewegliches System, mir gefällt es gut. Auf beispielsweise einem Ubuntu-System genügt ein
apt-get install graphite-web
. Wenn du das nicht möchtest oder für deine Plattform kein fertiges Paket existiert, muss es per Github gezogen werden; das ist der etwas steinigere Weg, aber nicht viel, es müssen halt ein paar Pfade angepasst werden.
$ cd /usr/src
$ git clone https://github.com/graphite-project/graphite-web.git
Cloning into 'graphite-web'...
remote: Counting objects: 19598, done.
remote: Compressing objects: 100% (35/35), done.
remote: Total 19598 (delta 9), reused 0 (delta 0), pack-reused 19563
Receiving objects: 100% (19598/19598), 19.14 MiB | 2.74 MiB/s, done.
Resolving deltas: 100% (12531/12531), done.
$ cd graphite-web
/usr/src/graphite-web$ ./check-dependencies.py
Ganz zu Anfang hatten wir per apt-get install
bereits alle benötigten Komponenten installiert, nicht unbedingt alle optionalen; sollte auf deinem System etwas fehlen, so siehst du es hier und kannst nachinstallieren. Bereit? Dann kann graphite-web
nun nach /opt/graphite
installiert werden:
$ /usr/src/graphite-web$ python setup.py install
Nun sorgen wir dafür, dass das Webinterface von graphite-web
auf Port 8000 verfügbar gemacht wird; dazu kopieren wir die apache2
-Konfiguration, die bei der Installation mitgebracht wurde, an Ort und Stelle, modifizieren sie ein wenig und starten den Webserver durch.
$ cp /opt/graphite/examples/example-graphite-vhost.conf /etc/apache2/sites-available/graphite-web.conf
Ich möchte, dass der Dienst auf Port 8000 läuft und dass WSGISocketPrefix
ein anderes ist als in der Default-Konfig vorgegeben:
## file: "/etc/apache2/sites-available/graphite-web.conf"
[...]
WSGISocketPrefix /var/run/apache2
[...]
## file: "/etc/apache2/ports.conf"
[...]
Listen 8000
[...]
Eine Konfiguration an Ort und Stelle zu legen ist glücklicherweise nicht kompliziert – es existiert eine Beispielkonfiguration, an der wir uns mühelos orientieren können.
$ /opt/graphite/webapp/graphite$ mv local_settings.py.example local_settings.py
Wird graphite-web
von Github gezogen, müssen hier einige Änderungen vorgenommen werden – zum Beispiel von WHISPER_DIR
, das zwingend nach /var/lib/graphite/whisper/
zeigen muss. Abschließend die neue Konfiguration aktivieren und dem Webserver einen Tritt geben:
$ a2ensite graphite-web.conf
Enabling site graphite-web.conf.
$ service apache2 restart
Jetzt erstellst du dir eine User-Datenbank:
$ /opt/graphite/webapp/graphite$ PYTHONPATH=/opt/graphite/webapp django-admin syncdb --settings=graphite.settings
Creating tables ...
Creating table account_profile
[...]
You just installed Django's auth system, which means you don't have any superusers defined.
Would you like to create one now? (yes/no): yes
Username (leave blank to use 'root'):
E-mail address: blog@spiller.me
Password:
Password (again):
Superuser created successfully.
Installing custom SQL ...
Installing indexes ...
Installed 0 object(s) from 0 fixture(s)
Theoretisch läuft das Webinterface nun also auf Port 8000; praktisch tut es nicht viel, außer eine Menge Fehler zu produzieren – die Logfiles finden sich übrigens unter /opt/graphite/storage/log/webapp/
!
-
„No such file or directory“ bei Javascript-Dateien
$ /opt/graphite$ ln -s webapp/content static
-
Target WSGI script not found or unable to stat: /opt/graphite/conf/graphite.wsgi
$ cd /opt/graphite/conf/ $ cp graphite.wsgi.example graphite.wsgi
-
IOError: [Errno 13] Permission denied: ‘/opt/graphite/storage/log/webapp/*‘**
chown -R www-data:www-data /opt/graphite
-
/opt/graphite/webapp/graphite/settings.py:235: UserWarning: SECRET_KEY is set to an unsafe default. This should be set in local_settings.py for better security
=> dann muss /opt/graphite/webapp/graphite/settings.py bearbeitet und der unsichere Default-Key durch einen guten ersetzt werden – für die Erzeugung gibt es auch Online-Generatoren, wenn man das möchte.)
Damit die spätere Aggregation der Daten in per carbon-cache
funktioniert, muss auch die Datei /etc/carbon/storage-schemas.conf
bearbeitet werden; es ist peinlich genau darauf zu achten, dass die Intervalle denen entsprechen, in denen Icinga2 seine Checks durchführt. Im folgenden Beispiel werden Checks, die jede Minute ausgeführt werden, für zwei Tage gespeichert (1m:2d
), Checks, die alle fünf Minuten ausgeführt werden, sollen für zehn Tage gespeichert werden (5m:10d
) – und so weiter. Passe an dieser Stelle die Konfiguration deinen Begebenheiten an!
[icinga_internals]
pattern = ^icinga\..*\.(max_check_attempts|reachable|current_attempt|execution_time|latency|state|state_type)
retentions = 5m:7d
[icinga_default]
pattern = ^icinga\.
retentions = 1m:2d,5m:10d,30m:90d,360m:4y
An dieser Stelle können die beteiligten Dienste nochmal durchgestartet werden; auf Port 8000 läuft nun graphite-web
und generiert aus den übermittelten Daten die ersten Graphen. Das ist großartig! Und nun müssen wir diese hübschen Bildchen lediglich noch in Icinga Web 2 einbinden…
icinga2-module-graphite
Ziehe dir per Github das Modul, das genau diese Arbeit verrichten wird:
$ cd /usr/share/icingaweb2/modules
$ git clone https://github.com/findmypast/icingaweb2-module-graphite graphite
Auf dem RaspPi musste ich den passenden Konfigurations-Ordner von Hand anlegen und eine Konfig hineinpacken:
$ mkdir /etc/icingaweb2/modules/graphite
## file: "/etc/icingaweb2/modules/graphite/config.ini"
[graphite]
base_url = http://YOUR.HOST.OR.IP:8000/render?
host_name_template = icinga.$host.name$.$metric$
service_name_template = icinga.$host.name$.$service.name$.$metric$
graphite_args_template = &target=$target$&width=300&height=120&hideAxes=false&lineWidth=2&hideLegend=true&colorList=049BAF&bgcolor=white&fgcolor=black
graphite_large_args_template = &target=$target$&width=800&height=700&colorList=049BAF&lineMode=connected&bgcolor=black&fgcolor=gray
Das entspricht nicht dem Default, der funktionierte hier nicht; auf meinem Ubuntu-System sieht die Konfiguration so aus:
## file: "/etc/icingaweb2/modules/graphite/config.ini"
[graphite]
base_url = http://YOUR.HOST.OR.IP:8000/render?
host_name_template = icinga2.$host.name$.host.$host.check_command$.perfdata.$metric$.value
service_name_template = icinga2.$host.name$.services.$service.name$.$service.check_command$.perfdata.$metric$.value
graphite_args_template = &target=$target$&source=0&width=300&height=120&hideAxes=false&lineWidth=2&hideLegend=true&colorList=049BAF&bgcolor=white&fgcolor=black
graphite_large_args_template = target=$target$&source=0&width=800&height=700&colorList=049BAF&lineMode=connected&bgcolor=black&fgcolor=gray
Hier musst du schauen, was von deinem System wie geliefert wird; während ich unter Ubuntu kaum etwas von Hand machen musste, war auf dem RaspPi relativ viel Handarbeit erforderlich. Wichtig ist auch zu beachten, dass der Punkt .
als Separator verwendet wird! Ich für meinen Teil war jedenfalls sehr glücklich, als ich es so weit geschafft hatte.
graphite und Nagvis
Zuletzt wollte ich meine neuen hübschen Graphen gerne in die hover
-Dateien von Nagvis einbinden; hier gibt es allerdings (noch?) Schwierigkeiten, vielleicht sollte ich auch einfach mal einen Feature Request stellen? Mein Default-Check für Hosts ist hostalive, und so kann ich für alle Hosts als Metrik rta angeben. Doch für die Services ist das nicht so einfach: bei jedem wäre eine andere Metrik von Interesse, und Nagvis gibt da derzeit nichts als Makro vor. Die einzige Metrik, die allen Services gemeinsam ist, ist latency, und die gibt nichts her. Aber wer weiß: vielleicht hat einer von euch eine Idee? ;-)
[...]
<table>
<tbody><tr><th><label>Performance Data</label></th></tr>
<!-- BEGIN service -->
<tr><td><img src="http://barbapapa.bafi.lan:8000/render/?width=586&height=308&target=icinga.[obj_name].[obj_display_name].latency" alt="latency"></td></tr>
<!-- END service -->
<!-- BEGIN host -->
<tr><td>Aufruf: icinga.[obj_name].rta</td></tr>
<tr><td><img src="http://barbapapa.bafi.lan:8000/render/?width=586&height=308&target=icinga.[obj_name].rta" alt="rta"></td></tr>
<!-- END host -->
</tbody></table>
[...]