Icinga Web 2 und graphite

Diesen Beitrag schrieb ich 8 Jahre und 3 Monate zuvor; die nachfolgenden Ausführungen müssen heute weder genau so nach wie vor funktionieren, noch meiner heutigen Meinung entsprechen. Behalte das beim Lesen (und vor allem: beim Nachmachen!) bitte stets im Hinterkopf.

Geschätzte Lesezeit: 4 Minuten

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

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

graphite module icingaweb2 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

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&amp;height=308&amp;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&amp;height=308&amp;target=icinga.[obj_name].rta" alt="rta"></td></tr>
  <!-- END host -->
</tbody></table>
[...]
Alle Bilder dieser Seite: © Marianne Spiller – Alle Rechte vorbehalten
Hintergrundbild: Bild genauer anschauen – © Marianne Spiller – Alle Rechte vorbehalten

Eure Gedanken zu „Icinga Web 2 und graphite“

Ich freue mich über jeden Kommentar, es sei denn, er ist blöd. Deshalb behalte ich mir auch vor, die richtig blöden kurzerhand wieder zu löschen. Die Kommentarfunktion ist über GitHub realisiert, weshalb ihr euch zunächst dort einloggen und „utterances“ bestätigen müsst. Die Kommentare selbst werden im Issue-Tracker und mit dem Label „✨💬✨ comment“ erfasst – jeder Blogartikel ist ein eigenes Issue. Über GitHub könnt ihr eure Kommentare somit jederzeit bearbeiten oder löschen.