theton
Bitmuncher
Da ich keinen besseren Platz gefunden habe, schreibe ich das folgende also einfach mal hier rein.
Performance-Monitoring - Eine kleine Howto-Geschichte
Oder: Wie mache ich meinem Chef kleine bunte Bildchen zur Server-Auslastung
Als ich in meiner Firma anfing, war von Server-Monitoring keine Spur. Es gab
zwar ein paar Skripte, mit denen man sich ein paar Statistiken aus den Logs
erstellen konnte und auch der Traffic wurde gemessen, aber Realtime-Monitoring
war hier ein Fremdwort. Nun, da ich eh das komplette Netzwerk umdesignen
wollte, weil mein Vorgaenger mir eigentlich nur ein grosses Chaos hinterlassen
hatte, machte ich mich auch ans Werk und richtete auf einem Server, der nun nur
noch fuer das Monitoring zustaendig ist, Nagios ein. Damit wurde ich zumindest
schonmal ueber meinen Pager informiert, wenn ein Server ausfiel. Stellte sich
mir nur die Frage nach einer sinnvollen Loesung um auch die Performance im
Auge zu behalten, denn schon in den ersten Tagen machte ich die Erfahrung, dass
einige der Server regelmaessig ueberlastet waren (ein Grund, warum ich mich
fuer den kompletten Neuaufbau des Netzwerks entschieden habe). BigSister gab
mir zumindest die Moeglichkeit Alarmmeldungen zu empfangen, wenn mal ein
Server ueberlastet war oder kein Platz mehr auf einer Festplatte hatte. Damit
waren die kritischen Punkte abgedeckt, aber es gab nichts, was der Chef sehen
konnte. Gut, er konnte sich bei Nagios und BigSister das Webinterface
anschauen, aber damit sah er auch nur den aktuellen Status und eine kurze
History ueber die "kritischen" Ereignisse der letzten Zeit. Hinzu kam, dass
Worte wie Apache-Webserver oder LDAP ein fremdwort waren. Er verstand also
nicht, was er da zu sehen bekam. Es musste also was her, das nach etwas aussah
und ihm alles schoen auf einem Blick moeglichst grafisch anzeigte.
1. Welche Software wird benoetigt?
Nachdem ich also eine Weile recherchiert hatte zum Thema Server-Monitoring
fiel mir auf, dass ein grossteil der Berichte auf ein Programm namens RRDTool
verwies. Bei freshmeat.net war das Programm auch nicht schwer zu finden und
schnell war es vom Server runtergeladen. Wie ich es ueblicherweise machte,
habe ich die Sourcen entpackt und erstmal mit ein paar Standard-Optionen
installiert. Das ging ganz einfach mit
Naja, wegen ein paar Bibliotheken meckerte configure dann schon noch rum, aber
die entsprechenden devel-Pakete waren schnell nachinstalliert und somit ging
die Installation recht zuegig und ohne grosse Komplikationen ab. Spaeter
stellte sich dann heraus, dass ich tatsaechlich mit diesen Optionen fuer
configure total richtig lag. "Das war ja einfach" dachte ich mir und gab
gleich mal
ein. Naja, ziemlich mager, was sich mir da praesentierte, allerdings gab es
noch einige Manpages zu den einzelnen Tools, die RRDTool mitbringt. Erst
spaeter fand ich heraus, dass es eigentlich nur Aliases fuer bestimmte
Funktionen von RRDTool sind. Hmm, sollte das etwa alles sein, was der mir an
Dokumentation installiert hat? Konnte ich mir eigentlich nicht vorstellen. Da
ich nach /usr/local installiert hatte, warf ich also mal einen Blick in
/usr/local/share/doc/rrdtool-<version> und siehe da, ich fand dort ein
html-Verzeichnis mit einer sehr ausfuehrlichen Doku. Das war mir dann aber
doch etwas zuviel. Mal zuviel, mal zuwenig, blieb also mal wieder nur mein
Freund das Internet. Ich brauchte auch nicht lange suchen und fand einige
Howtos zum Thema Performance-Monitoring mit RRDTool. Alle hatten nur einen
Haken... sie funktionierten nicht richtig. Bei jedem lief irgendwas schief,
wenn ich es ausprobierte. Naja, zumindest erhielt ich beim Lesen der Howtos
eine Einfuehrung in RRDTool und erfuhr, dass eine Round Robin Datenbank eine
Datenbank ist ist, deren "Speicherpunkte" kreisfoermig angeordnet sind und
ein Zeiger immer auf den aktuellen Punkt zeigt. Kommt der Zeiger wieder beim
ersten "Speicherpunkt" an, wird dieser ueberschrieben, so dass immer nur eine
aktuelle, aber begrenzte Datenmenge in der DB steht. Naja, und einige
nuetzliche Erklaerungen zu den Parametern fand ich auch.
Da ich bei der Systemadministration zum Ablegen von Daten und Skripten immer
auf den Servern ein Verzeichnis /root/scripts habe, erstellt ich mir da drin
einfach ein Verzeichnis fuer den ganzen RRDTool-Kram, denn ich ahnte schon,
dass es etwas mehr werden koennte.
2. Erstellen der RRDs
Danach also in dieses Verzeichnis gewechselt
und dann stand ich vor dem grossen Loch. Wie erstellt man nun so eine Datenbank
und in welcher Reihenfolge muss ich die Parameter angeben? Also doch nochmal
die Manpage zu Rate ziehen. Na das fing ja toll an. Wie ich Manpages hasse.
Warum kann man eine Software nicht so machen, dass ein einfaches --help als
Parameter genuegt und man bekommt eine Hilfe, die alles erklaert? Nunja,
aendern konnte ich es nicht, sonst haette die Sache noch laenger gedauert,
denn dann haette ich erstmal die Quelltexte modifizieren muessen. Nach vielem
Kopfzerbrechen und etwas rumprobieren kam ich dann letztendlich dazu eine Reihe
von Befehlen zusammenzustellen, die ich mir schnell in eine Datei schrieb,
damit sie nie wieder verloren gingen. Mit diesen konnte ich nun endlich die
richtigen RRDs erstellen. Zuerst einmal wollte ich eine RRD, in der ich die
Anzahl der Prozesse ablegen konnte
Dann noch eine fuer den Speicherverbrauch
Eine fuer die Durchschnittslast
Und fuer die 2 Partitionen wollte ich natuerlich auch Daten sammeln
Das wichtigste habe ich mir wie immer zum Schluss aufgehoben, damit ich genug
Zeit habe es zu vergessen und so erstellte ich, nachdem ich merkte, dass mir
was fehlte, auch noch eine RRD fuer die Netzwerklast der Netzwerkkarte des
Servers
3. Sammeln der Daten
Juchhu, ich hatte es geschafft. Yeah, endlich standen die RRDs und waren
bereit von mir mit Daten gefuettert zu werden. Kaum kam der Gedanke an die
Daten ging meine Euphorie auch schon wieder davon. Wie ich beim Studium der
Manpages gesehen hatte, musste ich dafuer wieder so elende Befehle ausfuehren.
"Nunja", dachte ich mir, "wenn ich die einmal habe, landen sie in einer Datei
und ich muss nie wieder etwas daran aendern." Gluecklicherweise sollte ich mit
dieser Vermutung Recht behalten. Ich hatte also nun 6 RRDs in meinem Verzeich-
nis: diskhda1.rrd, diskhda3.rrd, loadavg.rrd, memory.rrd, networketh0.rrd und
process.rrd. Fuer jede brauchte ich einen Befehl oder ein Skript um sie mit
Daten zu fuettern. Ich begann also bei den Festplatten. Die Belegung einer
Platte kann man wunderbar mit 'df' ermitteln und mit 'tr' und 'cut' die Zeichen
entfernen, die man nicht braucht. Ich kam also zu dem Befehl
Damit erhielt ich die aktuelle Belegung als einzelne Zahl und hatte einen Wert,
mit dem ich arbeiten konnte. Um nun das ganze in die RRD zu fuettern, bastelte
ich mir ein kleines Skript
Als ich dieses Skript nun also ausfuehrbar machte
konnte ich die Datenbank nun also mit den aktuellen Daten fuettern. Blieb nur
noch ein kleines Problem zu loesen. Wie sorge ich dafuer, dass dies in
bestimmten Abstaenden passiert? Wenn es um zeitgesteuerte Dinge ging, war Cron
schon immer mein Freund und so nahm ich mir vor erstmal alle Skripte fertig zu
machen und dann spaeter einfach Cron-Eintraege zu erstellen um sie in bestimm-
ten zeitlichen Abstaenden aufzurufen. Gedacht... getan.
Die Durchschnittslast kann man von der proc-Datei /proc/loadavg abfragen.
Schnell war also auch dafuer ein Skript gebastelt, das mir die 3 Werte fuer
die Durchschnittslast in der letzten Minute, den letzten 10 Minuten und der
letzten viertel Stunde getrennt mit Doppelpunkten gab und sie in die RRD
schrieb.
Dieses war der zweite Streich. Weiter ging es mit dem Speicher. Ueber den
erfaehrt man besonders viel ueber /proc/meminfo und wenn ich wieder die
unbrauchbaren Teile einfach abschnitt, bekam ich auch wieder Werte, die ich
verwenden konnte.
Nun fehlten also nur noch Netzwerk und Anzahl der Prozesse. Zuerst das
Netzwerk, diesmal wollte ich das Wichtigste mal ausnahmsweise nicht zuletzt
machen und alphabetisch gesehen kam in meinem 'ls'-Output jetzt auch die
network.rrd. Netzwerkinterface-Informationen konnte ich auch einfach aus
/proc/net/dev beziehen, um das Loopback nicht mit drin zu haben, filterte ich
also zuerst einmal alles aus, was mit eth0 zu tun hatte. Nun hatte ich
schonmal Informationen, die nur dieses Device betrafen. Die fuer mich
brauchbaren Informationen konnte ich mir also ganz einfach mit 'awk' ausfil-
tern. Dabei entstand dann also das vorletzte Skript zum Fuettern der RRDs.
Damit war auch das geschafft. Die Prozesse wurden nun ein Kinderspiel. Ich
brauchte ja einfach nur zu zaehlen, wieviele Zeilen der Output eines
vollstaendigen 'ps' hat. Schnell war also das letzte Skript fertig gestellt
4. Erstellen der Grafiken
Es war vollbracht. Ich hatte nun also Skripte, die alle RRDs mit den Daten
versorgen konnten, die ich haben wollte. Nun konnte ich aber schlecht meinem
Chef diese Dateien praesentieren und ihm sagen, dass da unsere Server-
Performance-Statistiken fuer die letzten 36 Stunden drin sind. Ich wollte ihm
ja was grafisches mit Kurven und so praesentieren. Etwas, was er anschauen
konnte, was schoen bunt war und ihm das Gefuehl gab, dass auf seine Server gut
aufgepasst wird. Fuer mich versteht es sich natuerlich von selbst, dass ich
meine Babies huete und ueberwache, wo es nur geht, aber das wusste er nicht,
dazu hatte ich zu wenig mit ihm zu tun. Ich musste aus diesen Daten also
irgendwie Bilder machen. Auch das ist mit RRDTool kein Problem. Ich erstellt
mir natuerlich auch dafuer ein Skript
5. Automatisierung
Als ich dieses Skript ausfuehrte, fand ich in meinem Verzeichnis tatsaechlich
die von mir gewuenschten Bilder. Ich kopierte sie also in das Webroot-Verzeich-
nis meines Webservers und als ich sie mir anschaute, konnte man tatsaechlich
ein paar kurze Striche darauf erkennen. Das waren die Daten von meinen Test,
die dort aufgezeichnet wurden. Es war nun also an der Zeit dafuer zu sorgen,
dass das ganze auch in regelmaessigen Abstaenden aktualisiert wurde, damit
Chef immer einigermassen aktuelle Daten sehen konnte. Ich fuegte also an meine
/etc/crontab ein paar Zeilen an, die dafuer sorgten, dass jede Minute neue
Daten in den RRDs landeten und alle 10 Minuten neue Bilder generiert wurden
Nachdem ich eine halbe Stunde gewartet hatte konnte ich klar erkennen, dass
alles tatsaechlich so funktionierte wie ich mir das vorgestellt hatte. Nun
fehlte nur noch der Feinschliff, denn meinem Chef eine Liste von Links zu den
Bildern zu schicken, war auch nicht fein. Ich musste sie also zentral auf
einem Webserver sammeln und schoen in einer kleinen Homepage verpacken. Zum
Testen hatte ich mir mittlerweile eh schon eine kleine HTML-Datei geschrieben,
die die Bilder schoen beschriftet anzeigte.
6. Zentrales Sammeln der Grafiken auf einem Server
Wie ich es schon oft gemacht hatte, wenn ich Daten von einem Server auf einen
anderen kopieren wollte, griff ich also wieder einmal zu 'man ssh-keygen'.
Wann werde ich mir diese verflixten Parameter endlich merken koennen? Beim
Lesen kam ich dann wieder drauf. Doch um eine Hostkey-Authentifizierung
aufzusetzen musste ich noch ein paar Vorbereitungen treffen. Ich deaktivierte
die Cronjobs voruebergehend und aenderte die Rechte fuer mein rrdtool-Verzeich-
nis so, dass sie nicht mehr root, sondern einem extra dafuer angelegten User
gehoerten.
Nun aenderte ich noch die Cronjobs entsprechend, so dass sie mit den Rechten
des neuen Users ausgefuehrt wurden und wechselte meine Identitaet
Jetzt war ich bereit die SSH-Schluessel zu generieren.
Dadurch erhielt ich 2 Dateien, ssh-server1.key und ssh-server1.key.pub. Den
oeffentlichen Schluessel aus der .pub-Datei musste ich nur noch in die Datei
authorized_keys im Verzeichnis .ssh/ des Webserver-Homeverzeichnisses ein-
tragen. Nun musste ich nach dem generieren der Bilder diese nur noch mit
auf den Webserver kopieren und konnte sie dort in einem Webinterface benutzen.
Die ganze Prozedur machte ich also auf allen unseren Servern, Rootservern wie
"lokalen", und praesentierte meinem Chef ein paar Tage spaeter ein Webinter-
face, in dem er sich all' die tollen bunten Bildchen anschauen konnte. Der war
happy, kann ich euch sagen. Ihr seht also, dass Chefs ganz einfach gluecklich
gemacht werden koennen.
Aber damit ihr auch noch was zum Nachdenken habt, erzaehle ich euch erst spae-
ter, wie ich die Uebersichten fuer eine ganze Woche gemacht habe. Wer aber
dieser Anleitung folgt, weiss zumindest, was in den letzten 36 Stunden auf
seinem Server passiert ist. Sicherlich lassen sich noch viele andere Sachen
auf diese Weise grafisch ueberwachen (denkbar waere z.B. die Ueberwachung der
Hardware mit lmsensors o.ae.), aber auch das ueberlasse ich ganz der Fantasie
des geneigten Lesers. Viel Spass beim Basteln.
Performance-Monitoring - Eine kleine Howto-Geschichte
Oder: Wie mache ich meinem Chef kleine bunte Bildchen zur Server-Auslastung
Als ich in meiner Firma anfing, war von Server-Monitoring keine Spur. Es gab
zwar ein paar Skripte, mit denen man sich ein paar Statistiken aus den Logs
erstellen konnte und auch der Traffic wurde gemessen, aber Realtime-Monitoring
war hier ein Fremdwort. Nun, da ich eh das komplette Netzwerk umdesignen
wollte, weil mein Vorgaenger mir eigentlich nur ein grosses Chaos hinterlassen
hatte, machte ich mich auch ans Werk und richtete auf einem Server, der nun nur
noch fuer das Monitoring zustaendig ist, Nagios ein. Damit wurde ich zumindest
schonmal ueber meinen Pager informiert, wenn ein Server ausfiel. Stellte sich
mir nur die Frage nach einer sinnvollen Loesung um auch die Performance im
Auge zu behalten, denn schon in den ersten Tagen machte ich die Erfahrung, dass
einige der Server regelmaessig ueberlastet waren (ein Grund, warum ich mich
fuer den kompletten Neuaufbau des Netzwerks entschieden habe). BigSister gab
mir zumindest die Moeglichkeit Alarmmeldungen zu empfangen, wenn mal ein
Server ueberlastet war oder kein Platz mehr auf einer Festplatte hatte. Damit
waren die kritischen Punkte abgedeckt, aber es gab nichts, was der Chef sehen
konnte. Gut, er konnte sich bei Nagios und BigSister das Webinterface
anschauen, aber damit sah er auch nur den aktuellen Status und eine kurze
History ueber die "kritischen" Ereignisse der letzten Zeit. Hinzu kam, dass
Worte wie Apache-Webserver oder LDAP ein fremdwort waren. Er verstand also
nicht, was er da zu sehen bekam. Es musste also was her, das nach etwas aussah
und ihm alles schoen auf einem Blick moeglichst grafisch anzeigte.
1. Welche Software wird benoetigt?
Nachdem ich also eine Weile recherchiert hatte zum Thema Server-Monitoring
fiel mir auf, dass ein grossteil der Berichte auf ein Programm namens RRDTool
verwies. Bei freshmeat.net war das Programm auch nicht schwer zu finden und
schnell war es vom Server runtergeladen. Wie ich es ueblicherweise machte,
habe ich die Sourcen entpackt und erstmal mit ein paar Standard-Optionen
installiert. Das ging ganz einfach mit
Code:
bash# ./configure --with-gnu-ld --prefix=/usr/local && make && make install
Naja, wegen ein paar Bibliotheken meckerte configure dann schon noch rum, aber
die entsprechenden devel-Pakete waren schnell nachinstalliert und somit ging
die Installation recht zuegig und ohne grosse Komplikationen ab. Spaeter
stellte sich dann heraus, dass ich tatsaechlich mit diesen Optionen fuer
configure total richtig lag. "Das war ja einfach" dachte ich mir und gab
gleich mal
Code:
bash# man rrdtool
ein. Naja, ziemlich mager, was sich mir da praesentierte, allerdings gab es
noch einige Manpages zu den einzelnen Tools, die RRDTool mitbringt. Erst
spaeter fand ich heraus, dass es eigentlich nur Aliases fuer bestimmte
Funktionen von RRDTool sind. Hmm, sollte das etwa alles sein, was der mir an
Dokumentation installiert hat? Konnte ich mir eigentlich nicht vorstellen. Da
ich nach /usr/local installiert hatte, warf ich also mal einen Blick in
/usr/local/share/doc/rrdtool-<version> und siehe da, ich fand dort ein
html-Verzeichnis mit einer sehr ausfuehrlichen Doku. Das war mir dann aber
doch etwas zuviel. Mal zuviel, mal zuwenig, blieb also mal wieder nur mein
Freund das Internet. Ich brauchte auch nicht lange suchen und fand einige
Howtos zum Thema Performance-Monitoring mit RRDTool. Alle hatten nur einen
Haken... sie funktionierten nicht richtig. Bei jedem lief irgendwas schief,
wenn ich es ausprobierte. Naja, zumindest erhielt ich beim Lesen der Howtos
eine Einfuehrung in RRDTool und erfuhr, dass eine Round Robin Datenbank eine
Datenbank ist ist, deren "Speicherpunkte" kreisfoermig angeordnet sind und
ein Zeiger immer auf den aktuellen Punkt zeigt. Kommt der Zeiger wieder beim
ersten "Speicherpunkt" an, wird dieser ueberschrieben, so dass immer nur eine
aktuelle, aber begrenzte Datenmenge in der DB steht. Naja, und einige
nuetzliche Erklaerungen zu den Parametern fand ich auch.
Da ich bei der Systemadministration zum Ablegen von Daten und Skripten immer
auf den Servern ein Verzeichnis /root/scripts habe, erstellt ich mir da drin
einfach ein Verzeichnis fuer den ganzen RRDTool-Kram, denn ich ahnte schon,
dass es etwas mehr werden koennte.
Code:
bash# mkdir -p /root/scripts/rrdtool
2. Erstellen der RRDs
Danach also in dieses Verzeichnis gewechselt
Code:
bash# cd /root/scripts/rrdtool
und dann stand ich vor dem grossen Loch. Wie erstellt man nun so eine Datenbank
und in welcher Reihenfolge muss ich die Parameter angeben? Also doch nochmal
die Manpage zu Rate ziehen. Na das fing ja toll an. Wie ich Manpages hasse.
Warum kann man eine Software nicht so machen, dass ein einfaches --help als
Parameter genuegt und man bekommt eine Hilfe, die alles erklaert? Nunja,
aendern konnte ich es nicht, sonst haette die Sache noch laenger gedauert,
denn dann haette ich erstmal die Quelltexte modifizieren muessen. Nach vielem
Kopfzerbrechen und etwas rumprobieren kam ich dann letztendlich dazu eine Reihe
von Befehlen zusammenzustellen, die ich mir schnell in eine Datei schrieb,
damit sie nie wieder verloren gingen. Mit diesen konnte ich nun endlich die
richtigen RRDs erstellen. Zuerst einmal wollte ich eine RRD, in der ich die
Anzahl der Prozesse ablegen konnte
Code:
bash# /usr/local/bin/rrdtool create process.rrd --step 60 DS:processes:GAUGE:120:U:U RRA:AVERAGE:0.5:1:2160 RRA:AVERAGE:0.5:5:2016 RRA:AVERAGE:0.5:15:2880 RRA:AVERAGE:0.5:60:8760 RRA:MAX:0.5:1:2160 RRA:MAX:0.5:5:2016 RRA:MAX:0.5:15:2880 RRA:MAX:0.5:60:8760
Dann noch eine fuer den Speicherverbrauch
Code:
bash# /usr/local/bin/rrdtool create memory.rrd --step 60 DS:fram:GAUGE:120:U:U DS:fswap:GAUGE:120:U:U RRA:AVERAGE:0.5:1:2160 RRA:AVERAGE:0.5:5:2016 RRA:AVERAGE:0.5:15:2880 RRA:AVERAGE:0.5:60:8760
Eine fuer die Durchschnittslast
Code:
bash# /usr/local/bin/rrdtool create loadavg.rrd --step 60 DS:load1:GAUGE:120:0:U DS:load5:GAUGE:120:0:U DS:load15:GAUGE:120:0:U RRA:AVERAGE:0.5:1:2160 RRA:AVERAGE:0.5:5:2016 RRA:AVERAGE:0.5:15:2880 RRA:AVERAGE:0.5:60:8760
Und fuer die 2 Partitionen wollte ich natuerlich auch Daten sammeln
Code:
bash# /usr/local/bin/rrdtool create diskhda1.rrd --step 300 DS:hda1:GAUGE:600:0:U RRA:AVERAGE:0.5:1:432 RRA:AVERAGE:0.5:1:2016 RRA:AVERAGE:0.5:3:2880 RRA:AVERAGE:0.5:12:8640
Code:
bash# /usr/local/bin/rrdtool create diskhda3.rrd --step 300 DS:hda3:GAUGE:600:0:U RRA:AVERAGE:0.5:1:432 RRA:AVERAGE:0.5:1:2016 RRA:AVERAGE:0.5:3:2880 RRA:AVERAGE:0.5:12:8640
Das wichtigste habe ich mir wie immer zum Schluss aufgehoben, damit ich genug
Zeit habe es zu vergessen und so erstellte ich, nachdem ich merkte, dass mir
was fehlte, auch noch eine RRD fuer die Netzwerklast der Netzwerkkarte des
Servers
Code:
bash# /usr/local/bin/rrdtool create networketh0.rrd --step 60 DS:eth0r:COUNTER:120:0:U DS:eth0t:COUNTER:120:0:U RRA:AVERAGE:0.5:1:2160 RRA:AVERAGE:0.5:5:2016 RRA:AVERAGE:0.5:15:2880 RRA:AVERAGE:0.5:60:8760 RRA:MAX:0.5:1:2160 RRA:MAX:0.5:5:2016 RRA:MAX:0.5:15:2880 RRA:MAX:0.5:60:8760
3. Sammeln der Daten
Juchhu, ich hatte es geschafft. Yeah, endlich standen die RRDs und waren
bereit von mir mit Daten gefuettert zu werden. Kaum kam der Gedanke an die
Daten ging meine Euphorie auch schon wieder davon. Wie ich beim Studium der
Manpages gesehen hatte, musste ich dafuer wieder so elende Befehle ausfuehren.
"Nunja", dachte ich mir, "wenn ich die einmal habe, landen sie in einer Datei
und ich muss nie wieder etwas daran aendern." Gluecklicherweise sollte ich mit
dieser Vermutung Recht behalten. Ich hatte also nun 6 RRDs in meinem Verzeich-
nis: diskhda1.rrd, diskhda3.rrd, loadavg.rrd, memory.rrd, networketh0.rrd und
process.rrd. Fuer jede brauchte ich einen Befehl oder ein Skript um sie mit
Daten zu fuettern. Ich begann also bei den Festplatten. Die Belegung einer
Platte kann man wunderbar mit 'df' ermitteln und mit 'tr' und 'cut' die Zeichen
entfernen, die man nicht braucht. Ich kam also zu dem Befehl
Code:
bash# df|grep hda3|tr -s [:blank:]| cut -f3 -d" "
Damit erhielt ich die aktuelle Belegung als einzelne Zahl und hatte einen Wert,
mit dem ich arbeiten konnte. Um nun das ganze in die RRD zu fuettern, bastelte
ich mir ein kleines Skript
Code:
bash# cat >> disk.sh
#!/bin/bash
OHDA3=`df|grep hda3|tr -s [:blank:]| cut -f3 -d" "`
HDA3=$(expr $OHDA3 \* 1024)
/usr/local/bin/rrdtool update /root/scripts/rrdtool/diskhda3.rrd N:$HDA3
OHDA1=`df|grep hda1|tr -s [:blank:]| cut -f3 -d" "`
HDA1=$(expr $OHDA1 \* 1024)
/usr/local/bin/rrdtool update /root/scripts/rrdtool/diskhda1.rrd N:$HDA1
[STRG+D]
Als ich dieses Skript nun also ausfuehrbar machte
Code:
bash# chmod u+x disk.sh
konnte ich die Datenbank nun also mit den aktuellen Daten fuettern. Blieb nur
noch ein kleines Problem zu loesen. Wie sorge ich dafuer, dass dies in
bestimmten Abstaenden passiert? Wenn es um zeitgesteuerte Dinge ging, war Cron
schon immer mein Freund und so nahm ich mir vor erstmal alle Skripte fertig zu
machen und dann spaeter einfach Cron-Eintraege zu erstellen um sie in bestimm-
ten zeitlichen Abstaenden aufzurufen. Gedacht... getan.
Die Durchschnittslast kann man von der proc-Datei /proc/loadavg abfragen.
Schnell war also auch dafuer ein Skript gebastelt, das mir die 3 Werte fuer
die Durchschnittslast in der letzten Minute, den letzten 10 Minuten und der
letzten viertel Stunde getrennt mit Doppelpunkten gab und sie in die RRD
schrieb.
Code:
bash# cat >> loadavg.sh
#!/bin/bash
# in der Praxis zeigte sich, dass die Last verfaelscht war,
# wenn dieses Skript zusammen mit den anderen lief. Warten wir
# also erstmal auf die anderen.
sleep 10
# Hier bekommen wir unsere 3 Werte 1min/10min/15min
LOAD=$(awk '{print $1":"$2":"$3}' < /proc/loadavg)
# rein damit in die RRD
/usr/local/bin/rrdtool update /root/scripts/rrdtool/loadavg.rrd N:$LOAD
[STRG+D]
Dieses war der zweite Streich. Weiter ging es mit dem Speicher. Ueber den
erfaehrt man besonders viel ueber /proc/meminfo und wenn ich wieder die
unbrauchbaren Teile einfach abschnitt, bekam ich auch wieder Werte, die ich
verwenden konnte.
Code:
bash# cat >> memory.sh
#!/bin/bash
# die Daten rund um RAM und SWAP kommen aus /proc/meminfo
# freier RAM
FREERAM=`grep MemFree: /proc/meminfo|tr -s [:blank:]|cut -f2 -d" "`
# freier Swap
FREESWAP=`grep SwapFree: /proc/meminfo|tr -s [:blank:]|cut -f2 -d" "`
# rein damit in die RRD
/usr/local/bin/rrdtool update /root/scripts/rrdtool/memory.rrd N:$FREERAM:$FREESWAP
[STRG+D]
Nun fehlten also nur noch Netzwerk und Anzahl der Prozesse. Zuerst das
Netzwerk, diesmal wollte ich das Wichtigste mal ausnahmsweise nicht zuletzt
machen und alphabetisch gesehen kam in meinem 'ls'-Output jetzt auch die
network.rrd. Netzwerkinterface-Informationen konnte ich auch einfach aus
/proc/net/dev beziehen, um das Loopback nicht mit drin zu haben, filterte ich
also zuerst einmal alles aus, was mit eth0 zu tun hatte. Nun hatte ich
schonmal Informationen, die nur dieses Device betrafen. Die fuer mich
brauchbaren Informationen konnte ich mir also ganz einfach mit 'awk' ausfil-
tern. Dabei entstand dann also das vorletzte Skript zum Fuettern der RRDs.
Code:
bash# cat >> network.sh
#!/bin/bash
# erstmal alles, was mit eth0 zu tun hat
ETH0=$(grep eth0 /proc/net/dev)
# hier merken wir uns den Downstream
E0DOWN=$(echo $ETH0|tr \: \ |awk '{print $2}')
# und hier wird der Upstream zwischengespeichert
E0UP=$(echo $ETH0|tr \: \ |awk '{print $10}')
# rein damit in die RRD
/usr/local/bin/rrdtool update /root/scripts/rrdtool/networketh0.rrd N:$E0DOWN:$E0UP
[STRG+D]
Damit war auch das geschafft. Die Prozesse wurden nun ein Kinderspiel. Ich
brauchte ja einfach nur zu zaehlen, wieviele Zeilen der Output eines
vollstaendigen 'ps' hat. Schnell war also das letzte Skript fertig gestellt
Code:
bash# cat >> process.sh
#!/bin/bash
# da spaeter noch andere Skripte laufen, die wir nicht mitzaehlen wollen,
# warten wir, bis diese fertig sind
sleep 15
# jetzt zaehlen wir die Prozesse
PROZESSE=$(ps hax|wc -l)
# rein damit in die RRD
/usr/local/bin/rrdtool update /root/scripts/rrdtool/process.rrd N:$PROZESSE
[STRG+D]
4. Erstellen der Grafiken
Es war vollbracht. Ich hatte nun also Skripte, die alle RRDs mit den Daten
versorgen konnten, die ich haben wollte. Nun konnte ich aber schlecht meinem
Chef diese Dateien praesentieren und ihm sagen, dass da unsere Server-
Performance-Statistiken fuer die letzten 36 Stunden drin sind. Ich wollte ihm
ja was grafisches mit Kurven und so praesentieren. Etwas, was er anschauen
konnte, was schoen bunt war und ihm das Gefuehl gab, dass auf seine Server gut
aufgepasst wird. Fuer mich versteht es sich natuerlich von selbst, dass ich
meine Babies huete und ueberwache, wo es nur geht, aber das wusste er nicht,
dazu hatte ich zu wenig mit ihm zu tun. Ich musste aus diesen Daten also
irgendwie Bilder machen. Auch das ist mit RRDTool kein Problem. Ich erstellt
mir natuerlich auch dafuer ein Skript
Code:
bash# cat >> make_png.sh
#!/bin/bash
# Anzahl der Prozesse
nice -n 19 /usr/local/bin/rrdtool graph /root/scripts/rrdtool/proc36h-server1.png --start -129600 -a PNG --vertical-label "Prozesse" -w 600 -h 100 DEF:auswertung=/root/scripts/rrdtool/process.rrd:processes:AVERAGE LINE1:auswertung#ff0000:"Anzahl Prozesse" VDEF:auswertung1=auswertung,AVERAGE GPRINT:auswertung1:"Durchschnitt Anzahl Prozesse\: %lg" DEF:maxaus=/root/scripts/rrdtool/process.rrd:processes:MAX VDEF:maxaus1=maxaus,MAXIMUM GPRINT:maxaus1:"Hoechste Anzahl Prozesse\: %lg\j" > /dev/null
# RAM und Swap
SWAPT=`grep SwapTotal: /proc/meminfo|tr -s [:blank:]|cut -f2 -d" "`
MEMT=`grep MemTotal: /proc/meminfo|tr -s [:blank:]|cut -f2 -d" "`
MEMTOTAL=$(expr $MEMT \* 1024)
SWAPTOTAL=$(expr $SWAPT \* 1024)
nice -n 19 /usr/local/bin/rrdtool graph /root/scripts/rrdtool/ramswap-server1.png -b 1024 --start -129600 -a PNG -t "RAM und SWAP" --vertical-label "Bytes" -w 700 -h 100 DEF:fram=/root/scripts/rrdtool/memory.rrd:fram:AVERAGE DEF:fswap=/root/scripts/rrdtool/memory.rrd:fswap:AVERAGE CDEF:framb=fram,1024,* CDEF:fswapb=fswap,1024,* CDEF:bram=$MEMTOTAL,framb,- CDEF:bswap=$SWAPTOTAL,fswapb,- CDEF:brammb=bram,1048576,/ CDEF:frammb=framb,1048576,/ CDEF:bswapmb=bswap,1048576,/ CDEF:fswapmb=fswapb,1048576,/ VDEF:brammb1=brammb,LAST VDEF:frammb1=frammb,LAST VDEF:bswapmb1=bswapmb,LAST VDEF:fswapmb1=fswapmb,LAST AREA:bram#99ffff:"belegter RAM, letzter\: " GPRINT:brammb1:"%7.3lf MB " LINE1:framb#ff0000:"freier RAM, letzter\: " GPRINT:frammb1:"%7.3lf MB Grafik erzeugt am\n" LINE1:bswap#000000:"belegter SWAP, letzter\: " GPRINT:bswapmb1:"%7.3lf MB " LINE1:fswapb#006600:"freier SWAP, letzter\: " GPRINT:fswapmb1:"%7.3lf MB $(/bin/date "+%d.%m.%Y %H\:%M\:%S")" > /dev/null
# Durchschnittslast
nice -n 19 /usr/local/bin/rrdtool graph /root/scripts/rrdtool/loadavg-server1.png --start -129600 -a PNG -t "Load Average" --vertical-label "Average Load" -w 600 -h 100 -M DEF:load1=/root/scripts/rrdtool/loadavg.rrd:load1:AVERAGE DEF:load5=/root/scripts/rrdtool/loadavg.rrd:load5:AVERAGE DEF:load15=/root/scripts/rrdtool/loadavg.rrd:load15:AVERAGE VDEF:load1l=load1,LAST VDEF:load5l=load5,LAST VDEF:load15l=load15,LAST AREA:load1#ff0000:"1 Minute, letzter\:" GPRINT:load1l:"%5.2lf\n" AREA:load5#ff9900:"5 Minuten, letzter\:" GPRINT:load5l:"%5.2lf Grafik erzeugt am\n" AREA:load15#ffff00:"15 Minuten, letzter\:" GPRINT:load15l:"%5.2lf $(/bin/date "+%d.%m.%Y %H\:%M\:%S")" LINE1:load5#ff9900:"" LINE1:load1#ff0000:"" > /dev/null
# Netzwerk
nice -n 19 /usr/local/bin/rrdtool graph /root/scripts/rrdtool/eth0-server1.png --start -129600 -a PNG -t "Network Interface eth0" --vertical-label "Bytes/s" -w 600 -h 100 -M DEF:eth0r=/root/scripts/rrdtool/networketh0.rrd:eth0r:AVERAGE DEF:eth0t=/root/scripts/rrdtool/networketh0.rrd:eth0t:AVERAGE CDEF:eth0tn=eth0t,-1,* VDEF:eth0ra=eth0r,AVERAGE VDEF:eth0rm=eth0r,MAXIMUM VDEF:eth0rc=eth0r,LAST VDEF:eth0ta=eth0t,AVERAGE VDEF:eth0tm=eth0t,MAXIMUM VDEF:eth0tc=eth0t,LAST COMMENT:" Durchschnitt Maximum aktuell pro Sekunde\n" AREA:eth0r#00dd00:"Receive " GPRINT:eth0ra:"%12.3lf %sb" GPRINT:eth0rm:"%12.3lf %sb" GPRINT:eth0rc:"%12.3lf %sb\n" AREA:eth0tn#0000ff:"Transmit" GPRINT:eth0ta:"%12.3lf %sb" GPRINT:eth0tm:"%12.3lf %sb" GPRINT:eth0tc:"%12.3lf %sb" > /dev/null
# hda3
nice -n 19 /usr/local/bin/rrdtool graph /root/scripts/rrdtool/hda3-server1.png -b 1024 --start -129600 -t "Belegung hda3 (EXT2)" --vertical-label "Bytes belegt" -w 600 -h 100 DEF:hda3=/root/scripts/rrdtool/diskhda3.rrd:hda3:AVERAGE AREA:hda3#00ff00:"belegter Platz" > /dev/null
# hda1
nice -n 19 /usr/local/bin/rrdtool graph /root/scripts/rrdtool/hda1-server1.png -b 1024 --start -129600 -t "Belegung hda1 (EXT2)" --vertical-label "Bytes belegt" -w 600 -h 100 DEF:hda1=/root/scripts/rrdtool/diskhda1.rrd:hda1:AVERAGE AREA:hda1#00ff00:"belegter Platz" > /dev/null
[STRG+D]
5. Automatisierung
Als ich dieses Skript ausfuehrte, fand ich in meinem Verzeichnis tatsaechlich
die von mir gewuenschten Bilder. Ich kopierte sie also in das Webroot-Verzeich-
nis meines Webservers und als ich sie mir anschaute, konnte man tatsaechlich
ein paar kurze Striche darauf erkennen. Das waren die Daten von meinen Test,
die dort aufgezeichnet wurden. Es war nun also an der Zeit dafuer zu sorgen,
dass das ganze auch in regelmaessigen Abstaenden aktualisiert wurde, damit
Chef immer einigermassen aktuelle Daten sehen konnte. Ich fuegte also an meine
/etc/crontab ein paar Zeilen an, die dafuer sorgten, dass jede Minute neue
Daten in den RRDs landeten und alle 10 Minuten neue Bilder generiert wurden
Code:
*/1 * * * * root /root/scripts/rrdtool/process.sh >> /var/log/monitoring.log
*/1 * * * * root /root/scripts/rrdtool/memory.sh >> /var/log/monitoring.log
*/1 * * * * root /root/scripts/rrdtool/loadavg.sh >> /var/log/monitoring.log
*/1 * * * * root /root/scripts/rrdtool/network.sh >> /var/log/monitoring.log
*/1 * * * * root /root/scripts/rrdtool/disk.sh >> /var/log/monitoring.log
*/10 * * * * root /root/scripts/rrdtool/make_png.sh >> /var/log/monitoring.log
Nachdem ich eine halbe Stunde gewartet hatte konnte ich klar erkennen, dass
alles tatsaechlich so funktionierte wie ich mir das vorgestellt hatte. Nun
fehlte nur noch der Feinschliff, denn meinem Chef eine Liste von Links zu den
Bildern zu schicken, war auch nicht fein. Ich musste sie also zentral auf
einem Webserver sammeln und schoen in einer kleinen Homepage verpacken. Zum
Testen hatte ich mir mittlerweile eh schon eine kleine HTML-Datei geschrieben,
die die Bilder schoen beschriftet anzeigte.
6. Zentrales Sammeln der Grafiken auf einem Server
Wie ich es schon oft gemacht hatte, wenn ich Daten von einem Server auf einen
anderen kopieren wollte, griff ich also wieder einmal zu 'man ssh-keygen'.
Wann werde ich mir diese verflixten Parameter endlich merken koennen? Beim
Lesen kam ich dann wieder drauf. Doch um eine Hostkey-Authentifizierung
aufzusetzen musste ich noch ein paar Vorbereitungen treffen. Ich deaktivierte
die Cronjobs voruebergehend und aenderte die Rechte fuer mein rrdtool-Verzeich-
nis so, dass sie nicht mehr root, sondern einem extra dafuer angelegten User
gehoerten.
Code:
bash# groupadd monitoring
bash# useradd -g monitoring -d /root/scripts/rrdtool monitoring
bash# chown -R monitoring:monitoring /root/scripts/rrdtool/
Nun aenderte ich noch die Cronjobs entsprechend, so dass sie mit den Rechten
des neuen Users ausgefuehrt wurden und wechselte meine Identitaet
Code:
bash# su - monitoring
Jetzt war ich bereit die SSH-Schluessel zu generieren.
Code:
bash$ ssh-keygen -t dsa -f ssh-server1.key
Dadurch erhielt ich 2 Dateien, ssh-server1.key und ssh-server1.key.pub. Den
oeffentlichen Schluessel aus der .pub-Datei musste ich nur noch in die Datei
authorized_keys im Verzeichnis .ssh/ des Webserver-Homeverzeichnisses ein-
tragen. Nun musste ich nach dem generieren der Bilder diese nur noch mit
Code:
bash$ cat >> make_png.sh
scp -i /root/scripts/rrdtool/ssh-server1.key /root/scripts/rrdtool/*.png \
webserver.meinefirma.de:/webhome/monitoring/
[STRG+D]
auf den Webserver kopieren und konnte sie dort in einem Webinterface benutzen.
Die ganze Prozedur machte ich also auf allen unseren Servern, Rootservern wie
"lokalen", und praesentierte meinem Chef ein paar Tage spaeter ein Webinter-
face, in dem er sich all' die tollen bunten Bildchen anschauen konnte. Der war
happy, kann ich euch sagen. Ihr seht also, dass Chefs ganz einfach gluecklich
gemacht werden koennen.
Aber damit ihr auch noch was zum Nachdenken habt, erzaehle ich euch erst spae-
ter, wie ich die Uebersichten fuer eine ganze Woche gemacht habe. Wer aber
dieser Anleitung folgt, weiss zumindest, was in den letzten 36 Stunden auf
seinem Server passiert ist. Sicherlich lassen sich noch viele andere Sachen
auf diese Weise grafisch ueberwachen (denkbar waere z.B. die Ueberwachung der
Hardware mit lmsensors o.ae.), aber auch das ueberlasse ich ganz der Fantasie
des geneigten Lesers. Viel Spass beim Basteln.