home Sonstiges Linux OpenBSD Links

Systemstatus mit RRDTool anzeigen

Mit RRDTool lassen sich Grafiken erstellen, die einen alles mögliche visualisieren lassen. Dazu benötigt RRDTool den Zeitpunkt und den Meßwert. Im Grunde läßt sich so ziemlich alles darstellen, was irgendwie mit Meßwerten und der Zeit zusammenhängt. Für die Systemüberwachung also ein prima Tool. Der Vorgänger MTRG habe ich bis heute nicht zum laufen gekriegt, ich finde ihn recht kryptisch.
Ein Dank geht an Daniel Bach, Udo Neist, David Thamm und Raymond Vetter, die mir Tipps und Anregungen gegeben haben.


Installation

Ich verwende hier die Version 1.2.19, die gibt es bei http://www.rrdtool.org zum Download. Es kann sein, das RRDTool noch einige andere Libs benötigt, das configure meckert dann rum und spukt auch gleich einen Link mit der Bezugsadresse aus. Die Installation verläuft nach dem bekannten Muster:
root@pd6000:~ # cd /usr/src/
root@pd6000:/usr/src # tar xfz /von/wo/auch/immer/rrdtool-1.2.19.tar.gz
root@pd6000:/usr/src # cd rrdtool-1.2.19
root@pd6000:/usr/src/rrdtool-1.2.19 # ./configure
root@pd6000:/usr/src/rrdtool-1.2.19 # make
root@pd6000:/usr/src/rrdtool-1.2.19 # make install
RRDTool wurde in das Verzeichnis /usr/local/rrdtool-1.2.19 installiert. Falls mal ein Update von RRDTool ansteht, habe ich keinen Bock alle Pfadnamen in den Scripten manuell anzupassen. Also setze ich einen symbolischen Link:
root@pd6000:/usr/src/rrdtool-1.2.19 # cd /usr/local
root@pd6000:/usr/local # ln -s rrdtool-1.2.19 rrdtool
RRDTool speichert die Daten in einer sogenannten Round Robin Database. Beim Erstellen einer Datenbank wird festgelegt, wie diese aus zu sehen hat. Es macht zum Beispiel keinen Sinn, jede Minute einen Wert zu speichern und daraus dann einen Zweijahresgraph erstellen zu lassen. Man kann mehrere Round Robin Databases in eine Datenbank packen.


Anzahl der Prozesse

Als erstes fangen wir mit etwas einfachen an, wir lassen uns die Anzahl der Prozesse einmal pro Minute anzeigen. Dabei soll dann so etwas herauskommen:

Damit alles seine Ordnung hat, landen die Datenbanken und Scripte im Verzeichnis /auktion/rrdtool. Die erzeugten Grafiken sollen mittels des Apache angezeigt werden. Dafür ist bei mir das Verzeichnis /auktion/apache/htdocs/monitoring vorgesehen.
Als erstes muß die RRD Datenbank angelegt werden:

root@pd6000:/usr/local # mkdir -p /auktion/rrdtool/process
root@pd6000:/usr/local # cd /auktion/rrdtool/process
root@pd6000:/auktion/rrdtool/process # /usr/local/rrdtool/bin/rrdtool \
create /auktion/rrdtool/process/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
Dieses Monster von Befehl sieht auf den ersten Blick recht heftig aus. Aber fangen wir mal an:
create /auktion/rrdtool/process/process.rrd legt die Datenbank an.
--step 60 alle 60 Sekunden erwartet die Datenbank einen neuen Wert.
DS:processes:GAUGE:120:U:U es wird eine Datenquelle (DS - Data Source) mit dem Namen processes angelegt, der Typ dieser DS ist GAUGE. Dies sagt der Datenbank, das es den Wert jedesmal komplett speichern soll. Es gibt noch einige andere Typen, je nach Einsatzgebiet. Es wird maximal 120 Sekunden darauf gewartet, das die Daten kommen. Danach wird UNKNOWN in die Datenbank geschrieben. Dadurch soll verhindert werden, das sich schlechte Mittelwerte bilden. Minimal und maximal erlaubte Werte schränke ich hier nicht ein, deshalb zweimal U. RRA:AVERAGE:0.5:1:2160 das erste Round Robin Archiv, es speichert den Mittelwert (AVERAGE, andere Typen sind möglich). 0.5 gibt die Abweichung an, die in die Datenbank geschrieben wird, wenn innerhalb des Intervals keine Daten kommen. Ist dieser Interval (hier in diesen Beispiel bei GAUGE mit 120 Sekunden) abgelaufen, wird UNKNOWN in die Datenbank geschrieben. 1:2160 - hier beginnt nun die Rechenarbeit. Das erste Round Robin Archiv soll uns einen guten Überblick über die letzten 36 Stunden geben. Die Rechnung geht wie folgt:
1 Stunde = 3600 Sekunden, 36 Stunden * 3600 = 129600 Sekunden, 1 Minute = 60 Sekunden, wir wollen jede Minute einen Wert speichern, 129600 / 60 = 2160
Die Anweisung RRA:AVERAGE:0.5:1:2160 reserviert also Platz für 2160 Einträge im ersten Round Robin Archiv.
Im zweiten Archiv geht es um eine Woche, jede Minute brauchen wir nicht mehr zu speichern, es reicht der Mittelwert aus fünf Minuten (es werden ja jede Minute Daten in die Datenbank geschrieben, aus fünf bildet dann dieses RRA den Mittelwert): 3600 Sekunden * 24 Stunden * 7 Tage = 604800 Sekunden / (5 Minuten * 60 Sekunden) = 2016 Werte
Im dritten Archiv soll ein Monat (wir gehen von 30 Tagen pro Monat aus) gespeichert werden. Der Mittelwert soll aus 15 Meßwerten erstellt werden: 3600 Sekunden * 24 Stunden * 30 Tage = 2592000 Sekunden / (15 Minuten * 60 Sekunden) = 2880 Werte
Im vierten Archiv reicht der Mittelwert aus einer Stunde aus um ein Jahr (365 Tage) darzustellen: 3600 Sekunden * 24 Stunden * 365 Tage = 31536000 Sekunden / (60 Minuten * 60 Sekunden) = 8760 Werte
Danach kommen nochmal vier RRA's, diesmal wird aber der Maximalwert gespeichert.

Der Sinn der Sache ist nun, das der jeweils letzte Zeitraum gespeichert wird. Jetzt haben wir den 3. Februar, das heißt, wenn ich die Monatsgrafik aufrufe, sehe ich die letzten 30 Tage. Ich kann aber zum Beispiel nicht einfach so die Monatsgrafik vom September aufrufen, es werden dann zwar schon ein paar Daten angezeigt, aber halt nicht mehr so genau wie die letzten 30 Tage, da die Datenbank dann nur noch die Daten auf der Jahres RRA rausziehen kann, welche wesentlich grober ist. Wer einen Server betreibt und nicht ab und zu mal seine Statistiken prüft, ist selber schuld.

Falls sich jetzt der eine oder andere RRDTool Profi an den Kopf fäßt und meint, das sei alles totaler Quatsch, so möge er mich verbessern. Die Infos habe ich mir zum großen Teil aus der Dokumentation und anderen Webseiten zusammengesucht.

Nachdem die Datenbank angelegt ist, muß sie auch gefüttert werden. Dazu schreiben wir ein kleines Shellscript /auktion/rrdtool/process/process.sh:

#!/bin/sh
# da später noch andere Scripte laufen, warten wir 15 Sekunden, bevor wir die Prozesse zählen sleep 15
# mit Hilfe von ps und wc die Anzahl der Prozesse ermitteln PROZESSE=$(ps hax|wc -l)
# zum Schluß kommen die Daten in die Datenbank # N steht für das aktuelle Datum und Uhrzeit /usr/local/rrdtool/bin/rrdtool update /auktion/rrdtool/process/process.rrd N:$PROZESSE
Damit das Script jede Minute ausgeführt wird (wurde ja so bei der Definition der Datenbank festgelegt) tragen wir es im cron ein:
root@pd6000:/auktion/rrdtool/process # crontab -e
am Ende folgende Zeile einfügen:
*/1 * * * *                     /auktion/rrdtool/process/process.sh
Falls man mit vi auf Kriegsfuß steht, kann man die Umgebungsvariable EDITOR auf einen Texteditor seiner Wahl setzen und danach erneut die crontab mit crontab -e bearbeiten.

Das Script sollte nun fleißig Daten sammeln, man sollte das am Timestamp der Datei process.rrd erkennen können.

Weiter geht es mir der Bilderzeugung. Auch dies erledigt ein Script (/auktion/rrdtool/erzeugepng.sh):

#!/bin/bash
# 36 Stunden - Prozesse
nice -n 19 /usr/local/rrdtool/bin/rrdtool graph /auktion/apache/htdocs/monitoring/proc36h.png \
--start -129600 -a PNG --vertical-label "Prozesse" -w 600 -h 100 \
DEF:auswertung=/auktion/rrdtool/process/process.rrd:processes:AVERAGE LINE1:auswertung#ff0000:"Anzahl Prozesse" > /dev/null
# 7 Tage - Prozesse
nice -n 19 /usr/local/rrdtool/bin/rrdtool graph /auktion/apache/htdocs/monitoring/procwoc.png \
--start -604800 -a PNG --vertical-label "Prozesse" -w 600 -h 100 \
DEF:auswertung=/auktion/rrdtool/process/process.rrd:processes:AVERAGE LINE1:auswertung#ff0000:"Anzahl Prozesse" > /dev/null
Aufbau eines Aufrufs:
nice -n 19 Grafiken erzeugen kann je nach Rechenpower etwas dauern, hiermit läuft es auf unterster Priorität.
/usr/local/rrdtool/bin/rrdtool graph rrdtool im Grafikerzeugemodus starten
/auktion/apache/htdocs/monitoring/proc36h.png dorthin soll die Grafik
--start -129600 es sollen die letzten 36 Stunden angezeigt werden (36 Stunden * 3600 Sekunden = 129600 Sekunden), alternativ kann man auch einen Bereich auswählen mit --start UNIX TIMESTAMP --end UNIX TIMESTAMP
-a PNG Grafikformat PNG, GIF und GD sind auch möglich
--vertical-label "Prozesse" Beschriftung der Y-Achse
-w 600 -h 100 Breite und Höhe des Graphen innerhalb des Bildes
DEF:auswertung=/auktion/rrdtool/process/process.rrd:processes:AVERAGE LINE1:auswertung#ff0000:"Anzahl Prozesse" DEF gibt an, wo unsere Daten herkommen, auswertung ist eine Variable für die Daten, innerhalb von rrdtool graph kann man noch einige Sachen damit anstellen (siehe Manpage), danach folgt die Datenbank und der Name der Daten (processes) und die Auswahl der RRA (AVERAGE oder MAX), die passende Zeit sucht sich RRDTool selber raus. Gezeichnet werden soll eine Linie aus der Variable auswertung in der Farbe rot (#ff0000). Die Beschriftung in der Legende folgt im Anschluß.
> /dev/null beim Erzeugen des Bildes spukt RRDTool ein paar Ausgaben aus, cron würde die jedesmal root zumailen, das wollen wir aber nicht

Dieses Script lasse ich nur zweimal in der Stunde (Minute 21 und 51) aufrufen, das ist aber reine Geschmackssache. Eintrag im crontab:

21,51 * * * *                   /auktion/rrdtool/erzeugepng.sh
Nachdem man mal ein paar Stunden lang Daten gesammelt hat, sollte man ein Bild ähnlich dieses erhalten:

In die Datenbank wurden aber auch die Maximalwerte gespeichert, es wäre schön, den Höchstwert und den Durchschnitt unten in der Legende angezeigt zu bekommen. Ein Titel für den Graph wäre auch nicht schlecht. Dazu muß die Datei /auktion/rrdtool/erzeugepng.sh geändert werden (rot markiert die Änderungen):

#!/bin/bash
# 36 Stunden - Prozesse
nice -n 19 /usr/local/rrdtool/bin/rrdtool graph /auktion/apache/htdocs/monitoring/proc36h.png \
--start -129600 -a PNG -t "Prozesse" --vertical-label "Prozesse" -w 600 -h 100 \
DEF:auswertung=/auktion/rrdtool/process/process.rrd:processes:AVERAGE LINE1:auswertung#ff0000:"Anzahl Prozesse" \
VDEF:auswertung1=auswertung,AVERAGE \
GPRINT:auswertung1:"Durchschnitt Anzahl Prozesse\: %lg" \
DEF:maxaus=/auktion/rrdtool/process/process.rrd:processes:MAX \
VDEF:maxaus1=maxaus,MAXIMUM \
GPRINT:maxaus1:"Höchste Anzahl Prozesse\: %lg\j" \
> /dev/null
# 7 Tage - Prozesse
nice -n 19 /usr/local/rrdtool/bin/rrdtool graph /auktion/apache/htdocs/monitoring/procwoc.png \
--start -604800 -a PNG -t "Prozesse" --vertical-label "Prozesse" -w 600 -h 100 \
DEF:auswertung=/auktion/rrdtool/process/process.rrd:processes:AVERAGE LINE1:auswertung#ff0000:"Anzahl Prozesse" \
VDEF:auswertung1=auswertung,AVERAGE \
GPRINT:auswertung1:"Durchschnitt Anzahl Prozesse\: %lg" \
DEF:maxaus=/auktion/rrdtool/process/process.rrd:processes:MAX \
VDEF:maxaus1=maxaus,MAXIMUM \
GPRINT:maxaus1:"Höchste Anzahl Prozesse\: %lg\j" \
> /dev/null
Das Bild sollte dann so aussehen:

Neu hinzugekommen sind die Parameter VDEF und GPRINT. GPRINT dient dazu, Eintragungen unterhalb des Graphen vorzunehmen. Es gibt hier einige Parameter zur Formatierung. Beim zweiten GPRINT wäre dies zum Beispiel \j. Dieser dient dazu, das sich die Einträge gleichmäßig verteilen. %lg ist ein Platzhalter für den Wert. VDEF dient praktisch als Vorarbeiter für GPRINT. VDEF:maxaus1=maxaus,MAXIMUM schreibt zum Beispiel den maximalen Wert aus der DEF maxaus in die Variable maxaus1. maxaus1 kann dann von GPRINT angezeigt werden.


RAM und Swap

Weiter geht es mit der Auslastung des RAM und Swap. Auch diese erwarten Daten im Abstand von einer Minute. Hier bauen wir nun eine etwas größere RRD zusammen:
root@pd6000:/auktion/rrdtool/process # mkdir -p /auktion/rrdtool/memory
root@pd6000:/auktion/rrdtool/process # cd /auktion/rrdtool/memory
root@pd6000:/auktion/rrdtool/memory # /usr/local/rrdtool/bin/rrdtool \
create /auktion/rrdtool/memory/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
Das Script /auktion/rrdtool/memory/memory.sh dazu:
#!/bin/bash
# die Daten rund um RAM und SWAP kommen aus /proc/meminfo # freier RAM FRAM=`grep MemFree: /proc/meminfo|tr -s [:blank:]|cut -f2 -d" "` # freier Swap FSWAP=`grep SwapFree: /proc/meminfo|tr -s [:blank:]|cut -f2 -d" "`
# rein damit in die RRD /usr/local/rrdtool/bin/rrdtool update /auktion/rrdtool/memory/memory.rrd N:$FRAM:$FSWAP
An /auktion/rrdtool/erzeugepng.sh hängen wir folgende Zeilen an:
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)
# 36 Stunden - RAM und Swap in einen nice -n 19 /usr/local/rrdtool/bin/rrdtool graph /auktion/apache/htdocs/monitoring/ramswap.png \ -b 1024 --start -129600 -a PNG -t "RAM und SWAP" --vertical-label "Bytes" -w 700 -h 100 \ DEF:fram=/auktion/rrdtool/memory/memory.rrd:fram:AVERAGE \ DEF:fswap=/auktion/rrdtool/memory/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
# 7 Tage - RAM und Swap in einen nice -n 19 /usr/local/rrdtool/bin/rrdtool graph /auktion/apache/htdocs/monitoring/ramwoc.png \ -b 1024 --start -604800 -a PNG -t "RAM und SWAP" --vertical-label "Bytes" -w 700 -h 100 \ DEF:fram=/auktion/rrdtool/memory/memory.rrd:fram:AVERAGE \ DEF:fswap=/auktion/rrdtool/memory/memory.rrd:fswap:AVERAGE \ CDEF:framb=fram,1024,* \ CDEF:fswapb=fswap,1024,* \ CDEF:bram=$MEMTOTAL,framb,- \ CDEF:bswap=$SWAPTOTAL,fswapb,- \ AREA:bram#99ffff:"belegter RAM" \ LINE1:framb#ff0000:"freier RAM" \ LINE1:bswap#000000:"belegter SWAP" \ LINE1:fswapb#006600:"freier SWAP" > /dev/null
Ein paar neue Kommandos sind hier mit drin. -b 1024 gibt an, wie die Umrechnung zwischen Kilo, Mega und so weiter erfolgen soll. Standard sind 1000, aber bei Speicher haben wir nun mal 1024.
CDEF's sind dafür da, um weitere Berechnungen vorzunehmen. Das Prinzip ist ganz einfach: neue Variable=alte Variable,andere Variable oder Wert, Operation. Man kann CDEF's auch zu längeren Konstrukten zusammenbauen, siehe hier zu die Manpage oder das CDEF Tutorial auf der RRDTool Homepage.
Man kann mehrere Linien definieren (auch wenn sie hier alle den Namen LINE1 haben, alternativ sind noch LINE2 und LINE3 möglich, die Ziffer gibt die Dicke der Linie an) und auch eine sogenannte Area. Diese ist im Endeffekt eine Linie, in der aber der Abstand bis zum Nullpunkt ebenfalls mit der angegebenen Farbe ausgefüllt wird.
Zu beachten ist der Platzhalter %7.3lf im GPRINT. Dies gibt an, das dort ein Wert mit drei Stellen vor und nach dem Punnkt angezeigt wird. Ursprünglich ging ich davon aus, das man dies mit %3.3lf erreicht, aber da lag ich falsch.
Zu guter letzt lassen wir uns noch das Datum anzeigen, wann der Graph erstellt wurde. Ob man das mit jeder Grafik macht, ist reine Geschmackssache.

Die Daten sollen jede Minute eingetragen werden, also folgender Eintrag im cron:

*/1 * * * *                     /auktion/rrdtool/memory/memory.sh
Wenn es klappt, sollte man eine Grafik ähnlich dieser erhalten:


Load Average

Mit dem Load Average läßt sich ebenfalls die Systemauslastung erkennen. Auslesen kann man ihn zum Beispiel aus der Datei /proc/loadavg. Der Load Average besteht aus drei Werten: der erste gibt die Auslastung der letzten Minute an, der zweite die Auslastung der letzten fünf und der dritte die letzten fünfzehn Minuten. Einrichtung:
root@pd6000:/auktion/rrdtool/memory # mkdir -p /auktion/rrdtool/loadavg
root@pd6000:/auktion/rrdtool/memory # cd /auktion/rrdtool/loadavg
root@pd6000:/auktion/rrdtool/loadavg # /usr/local/rrdtool/bin/rrdtool \
create /auktion/rrdtool/loadavg/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
Das Script (/auktion/rrdtool/loadavg/loadavg.sh) zum Eintragen der Daten sieht so aus:
#!/bin/sh
LOAD=$(awk '{print $1":"$2":"$3}' < /proc/loadavg)
/usr/local/rrdtool/bin/rrdtool update /auktion/rrdtool/loadavg/loadavg.rrd N:$LOAD
cron nicht vergessen:
*/1 * * * *                     /auktion/rrdtool/loadavg/loadavg.sh
Irgendwann wollen wir auch ein Bild, also an /auktion/rrdtool/erzeugepng.sh folgende Zeilen anhängen:
# 36 Stunden - Load Average
nice -n 19 /usr/local/rrdtool/bin/rrdtool graph /auktion/apache/htdocs/monitoring/loadavg.png --start -129600 \
-a PNG -t "Load Average" --vertical-label "Average Load" -w 600 -h 100 -M \
DEF:load1=/auktion/rrdtool/loadavg/loadavg.rrd:load1:AVERAGE \
DEF:load5=/auktion/rrdtool/loadavg/loadavg.rrd:load5:AVERAGE \
DEF:load15=/auktion/rrdtool/loadavg/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
# 7 Tage - Load Average
nice -n 19 /usr/local/rrdtool/bin/rrdtool graph /auktion/apache/htdocs/monitoring/load7.png --start -604800 \
-a PNG -t "Load Average" --vertical-label "Average Load" -w 600 -h 100 \
DEF:load1=/auktion/rrdtool/loadavg/loadavg.rrd:load1:AVERAGE \
DEF:load5=/auktion/rrdtool/loadavg/loadavg.rrd:load5:AVERAGE \
DEF:load15=/auktion/rrdtool/loadavg/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
Zuerst werden die Areas gezeichnet, danach noch mal die Ein und Fünf Minuten Load als LINE1 extra. Der Grund ist, das diese beiden Load schneller fallen als die Fünfzehn Minuten Load und man will ja was sehen ;). Folgende Grafik ist auf zwei Stunden erzeugt und sollte es veranschaulichen. Übrigens muß man schon einige Prozesse starten, um einen 600er VIA C3 auf einen Load von 1 zu bekommen (aber zur Not tut es einfach mal Seti@home). Normalerweise idlet der Rechner mit 0,0 bis 0,1 vor sich hin...


Auslastung der Festplatten

Was nicht fehlen darf, ist die Auslastung der Festplatten. Bei mir sind dies zwei (hda3 und hda5). Es reicht alle fünf Minuten einen Wert zu speichern:
root@pd6000:/auktion/rrdtool/loadavg # mkdir -p /auktion/rrdtool/disk
root@pd6000:/auktion/rrdtool/loadavg # cd /auktion/rrdtool/disk
root@pd6000:/auktion/rrdtool/disk # /usr/local/rrdtool/bin/rrdtool create /auktion/rrdtool/disk/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
root@pd6000:/auktion/rrdtool/disk # /usr/local/rrdtool/bin/rrdtool create /auktion/rrdtool/disk/diskhda5.rrd --step 300 \
DS:hda5: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 Script (/auktion/rrdtool/disk/disk.sh) zum Eintragen:
#!/bin/sh
KHDA3=`df|grep hda3|tr -s [:blank:]| cut -f3 -d" "`
HDA3=$(expr $KHDA3 \* 1024)
KHDA5=`df|grep hda5|tr -s [:blank:]| cut -f3 -d" "`
HDA5=$(expr $KHDA5 \* 1024)
/usr/local/rrdtool/bin/rrdtool update /auktion/rrdtool/disk/diskhda3.rrd N:$HDA3
/usr/local/rrdtool/bin/rrdtool update /auktion/rrdtool/disk/diskhda5.rrd N:$HDA5
Bilderzeugung (an /auktion/rrdtool/erzeugepng.sh) anhängen:
# hda3
nice -n 19 /usr/local/rrdtool/bin/rrdtool graph /auktion/apache/htdocs/monitoring/hda3.png  -b 1024 --start -129600 \
-t "Belegung hda3 (EXT2)" --vertical-label "Bytes belegt" -w 600 -h 100 \
DEF:hda3=/auktion/rrdtool/disk/diskhda3.rrd:hda3:AVERAGE AREA:hda3#00ff00:"belegter Platz" > /dev/null
nice -n 19 /usr/local/rrdtool/bin/rrdtool graph /auktion/apache/htdocs/monitoring/hda3-7.png -b 1024 --start -604800 \
-t "Belegung hda3 (EXT2)" --vertical-label "Bytes belegt" -w 600 -h 100 \
DEF:hda3=/auktion/rrdtool/disk/diskhda3.rrd:hda3:AVERAGE AREA:hda3#00ff00:"belegter Platz" > /dev/null

# hda5 nice -n 19 /usr/local/rrdtool/bin/rrdtool graph /auktion/apache/htdocs/monitoring/hda5.png -b 1024 --start -129600 \ -t "Belegung hda5 (XFS)" --vertical-label "Bytes belegt" -w 600 -h 100 \ DEF:hda5=/auktion/rrdtool/disk/diskhda5.rrd:hda5:AVERAGE AREA:hda5#00ff00:"belegter Platz" > /dev/null nice -n 19 /usr/local/rrdtool/bin/rrdtool graph /auktion/apache/htdocs/monitoring/hda5-7.png -b 1024 --start -604800 \ -t "Belegung hda5 (XFS)" --vertical-label "Bytes belegt" -w 600 -h 100 \ DEF:hda5=/auktion/rrdtool/disk/diskhda5.rrd:hda5:AVERAGE AREA:hda5#00ff00:"belegter Platz" > /dev/null

Der cron muß auch Bescheid wissen:
*/5 * * * *                     /auktion/rrdtool/disk/disk.sh
Das Ergebnis sollte irgendwie ähnlich diesen aussehen:


Temperaturmessung

Unter http://lena.franken.de/hardware/temperaturmessung.html habe ich eine Anleitung gefunden, wie man mit Linux über den seriellen Port Temperaturen messen kann.

Möglich ist dies mit einer kleinen Schaltung, die bequem in einen 25poligen Steckergehäuse Platz hat. An die Schaltung kann man mehrere Sensoren parallel anschließen. Zwei gehen auf jedenfall (ein Sensor hängt bei mir im Gehäuse, der andere im Zimmer). Auch das Anschlußkabel kann etwas länger sein. Der erste Sensor ist bei mir nach 30 cm Kabel an der Reihe, zum zweiten sind es dann noch mal 150 cm.
Die Bauteilkosten belaufen sich auf ungefähr 11 €. Die Bauteile kann man zum Beispiel bei der Firma Reichelt Elektronik bestellen. Folgende Teile werden benötigt:

Reichelt Artikel-Nr.AnzahlBeschreibung
ZF 6,21Z-DIODE 0,5W
ZF 3,91Z-DIODE 0,5W
1/4W 1,5K1Kohleschichtwiderstand 1/4W, 5%, 1,5 kOhm
DS 18S202Temperatursensor
1N 58182Diode
D-SUB BU 251D-SUB-Buchse, 25-polig, Lötkelch
KAPPE CG25G1D-SUB-Kappe für 25-polig D-SUB
Das ganze sollte wie folgt zusammen gelötet werden:

Die Temperatursensorgen werden wie folgt angeschlossen: den Sensoren so hinlegen, das die flache Seite mit der Schrift nach oben zeigt. Der linke Pin ist der GND, der mittlere ist DATA und der rechte wird nicht benötigt.

Um die Temperatursensoren überhaupt abzufragen, braucht man natürlich auch die passende Software. Ich verwende digitemp in der Version 3.3.2. Downloaden kann man es von http://www.digitemp.com/software.shtml. Dazu kommt noch ein Patch aus dem Debianprojekt: ftp://ftp.debian.org/debian/pool/main/d/digitemp/digitemp_3.3.2-2.diff.gz.

root@pd6000:/auktion/rrdtool/disk # cd /usr/src
root@pd6000:/usr/src # tar xfz /von/wo/auch/immer/digitemp-3.3.2.tar.gz
root@pd6000:/usr/src # cp /von/wo/auch/immer/digitemp_3.3.2-2.diff.gz .
root@pd6000:/usr/src # gunzip digitemp_3.3.2-2.diff.gz
root@pd6000:/usr/src # cd digitemp-3.3.2
root@pd6000:/usr/src/digitemp-3.3.2 # patch -Np1 -i ../digitemp_3.3.2-2.diff
root@pd6000:/usr/src/digitemp-3.3.2 # make ds9097
root@pd6000:/usr/src/digitemp-3.3.2 # make install
root@pd6000:/usr/src/digitemp-3.3.2 # ln -s /usr/bin/digitemp_DS9097 /usr/local/bin/digitemp
Digitemp wird in /usr/bin installiert. Da ich aber das Programm mit digitemp direkt aufrufen will als mit digitemp_DS9097, habe ich noch einen symbolischen Link gesetzt. Als erstes muß eine Configdatei erstellt werden. Dabei kann man auch gleich sehen, ob die beiden Sensoren gefunden werden:
root@pd6000:/usr/src/digitemp-3.3.2 # /usr/local/bin/digitemp -i -s/dev/ttyS1 -c/etc/digitemprc
DigiTemp v3.3.2 Copyright 1996-2004 by Brian C. Lane
GNU Public License v2.0 - http://www.brianlane.com
Turning off all DS2409 Couplers
..
Searching the 1-Wire LAN
108C30880008005B : DS1820/DS18S20/DS1920 Temperature Sensor
108E2E88000800EB : DS1820/DS18S20/DS1920 Temperature Sensor
ROM #0 : 108E2E88000800EB
ROM #1 : 108C30880008005B
Wrote /etc/digitemprc
root@pd6000:/usr/src/digitemp-3.3.2 # /usr/local/bin/digitemp -a -c/etc/digitemprc
DigiTemp v3.3.2 Copyright 1996-2004 by Brian C. Lane
GNU Public License v2.0 - http://www.brianlane.com
Oct 03 15:20:18 Sensor 0 C: 21.19 F: 82.06
Oct 03 15:20:20 Sensor 1 C: 27.81 F: 70.14
Welcher Sensor welcher ist, muß man selbst rausfinden, im Zweifelsfall mit einem Fön oder ähnliches nachhelfen ;). Bei mir ist der Sensor 0 der im Gehäuse und der andere hängt im Zimmer.

Weiter geht es mit RRDTool, als erstes brauchen wir erst mal eine neue Datenbank:

root@pd6000:/usr/src/digitemp-3.3.2 # mkdir -p /auktion/rrdtool/temperatur
root@pd6000:/usr/src/digitemp-3.3.2 # cd /auktion/rrdtool/temperatur
root@pd6000:/auktion/rrdtool/temperatur # /usr/local/rrdtool/bin/rrdtool \
create /auktion/rrdtool/temperatur/temperatur.rrd --step 60 \
DS:gehaeuse:GAUGE:120:U:U \
DS:zimmer: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:MIN:0.5:1:2160 \
RRA:MIN:0.5:5:2016 \
RRA:MIN:0.5:15:2880 \
RRA:MIN: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
Zum Einlesen der Daten wird die Datei /auktion/rrdtool/temperatur/temperatur.sh mit folgenden Inhalt erstellt:
#!/bin/sh
# Parameter von digitemp:
# -t0 oder -t1 : fragt den ersten oder zweiten Sensor ab
# -q : nur die Temperatur ausgeben, keine anderen Informationen
# -c/etc/digitemprc : das ist die vorhin erstellte Configdatei
GEHAEUSE=`/usr/local/bin/digitemp -t0 -q -c/etc/digitemprc | tr -s [:blank:] | cut -f7 -d" "`
ZIMMER=`/usr/local/bin/digitemp -t1 -q -c/etc/digitemprc | tr -s [:blank:] | cut -f7 -d" "`
/usr/local/rrdtool/bin/rrdtool update /auktion/rrdtool/temperatur/temperatur.rrd N:$GEHAEUSE:$ZIMMER
Der cron will nicht vergessen werden, folgende Zeile einfügen:
*/1 * * * *                     /auktion/rrdtool/temperatur/temperatur.sh
Folgende Zeilen in /auktion/rrdtool/erzeugepng.sh eingefügt erzeugen die zwei Graphen:
nice -n 19 /usr/local/rrdtool/bin/rrdtool graph /auktion/apache/htdocs/monitoring/temperaturg.png -a PNG -b 1024 --start -129600 -A \
-l -10 -u 70 -t "Gehäuse Temperatur" --vertical-label "Grad Celsius" -w 600 -h 200 \
DEF:g1=/auktion/rrdtool/temperatur/temperatur.rrd:gehaeuse:AVERAGE \
DEF:gmin=/auktion/rrdtool/temperatur/temperatur.rrd:gehaeuse:MIN \
DEF:gmax=/auktion/rrdtool/temperatur/temperatur.rrd:gehaeuse:MAX \
VDEF:g1a=g1,LAST \
VDEF:gmina=gmin,MINIMUM \
VDEF:gmaxa=gmax,MAXIMUM \
LINE2:g1#ff0000:"Gehäuse Temperatur" \
GPRINT:g1a:"aktuell\: %5.2lf °C" \
GPRINT:gdurch:"Durchschnitt\: %5.2lf °C\n" \
GPRINT:gmina:"tiefste\: %5.2lf °C" \
GPRINT:gmaxa:"höchste\:      %5.2lf °C" > /dev/null
nice -n 19 /usr/local/rrdtool/bin/rrdtool graph /auktion/apache/htdocs/monitoring/temperaturz.png -a PNG -b 1024 --start -129600 -A \ -l -10 -u 60 -t "Zimmer Temperatur" --vertical-label "Grad Celsius" -w 600 -h 200 \ DEF:g1=/auktion/rrdtool/temperatur/temperatur.rrd:zimmer:AVERAGE \ DEF:gmin=/auktion/rrdtool/temperatur/temperatur.rrd:gehaeuse:MIN \ DEF:gmax=/auktion/rrdtool/temperatur/temperatur.rrd:gehaeuse:MAX \ VDEF:g1a=g1,LAST \ VDEF:gmina=gmin,MINIMUM \ VDEF:gmaxa=gmax,MAXIMUM \ LINE2:g1#ff0000:"Zimmer Temperatur" \ GPRINT:g1a:"aktuell\: %5.2lf °C" \ GPRINT:gdurch:"Durchschnitt\: %5.2lf °C\n" \ GPRINT:gmina:"tiefste\: %5.2lf °C" \ GPRINT:gmaxa:"höchste\: %5.2lf °C" > /dev/null
Neu sind die Parameter -l -10 und -u 70 beziehungsweise -u 60. Diese beiden Werte geben an, welchen Wertebereich der Graph auf jedenfall anzeigen soll, egal ob dort "Treffer" drin liegen oder nicht.

Wenn alles klappt, sollte man einen Graphen ähnlich diesen erhalten (hier als Beispiel die Anzeige der letzten zwei Stunden):


Manchmal kann es auch sinnvoll sein, wenn ein Graph mehrfarbig dargestellt wird. Im nachfolgenden Beispiel wird über 22 °C der Graph rot, zwischen 15 und 22 °C grün und unter 15 °C blau dargestellt.


Um einen mehrfarbigen Graph darzustellen, muß man sich der CDEFs bedienen. Eine CDEF kann auch als IF Anweisung genutzt werden. Der grüne Graph wird mit einen leicht größeren Wertebereich angegeben, sonst hat man unter Umständen "Löcher" im Graph. Es wird noch mal ein extra roter Graph gezeichnet, damit es bei der Überlappung zwischen rot und grün einfach besser aussieht. Der Graph wurde mit folgenden Befehl erzeugt:

/usr/local/rrdtool/bin/rrdtool graph /auktion/apache/htdocs/monitoring/temperaturz.png \
-a PNG -b 1024 --start -7200 -A \
-l -5 -u 40 -t "Zimmer Temperatur" --vertical-label "Grad Celsius" -w 600 -h 200 \
DEF:g1=/auktion/rrdtool/temperatur/temperatur.rrd:zimmer:AVERAGE \
DEF:gmin=/auktion/rrdtool/temperatur/temperatur.rrd:zimmer:MIN \
DEF:gmax=/auktion/rrdtool/temperatur/temperatur.rrd:zimmer:MAX \
VDEF:g1a=g1,LAST \
VDEF:gmina=gmin,MINIMUM \
VDEF:gmaxa=gmax,MAXIMUM \
CDEF:blau=g1,15,LT,g1,UNKN,IF \
CDEF:rot=g1,22,GT,g1,UNKN,IF \
CDEF:gzw=g1,23,LT,g1,UNKN,IF \
CDEF:gruen=gzw,10,GT,gzw,UNKN,IF \
LINE2:rot#ff0000:"Zimmer Temperatur über 22 °C," \
LINE2:gruen#00ff00:"zwischen 15 und 22 °C" \
LINE2:blau#0000ff:"Temperatur unter 15 °C\n" \
LINE2:rot#ff0000: \
GPRINT:gmina:"Tiefsttemperatur\: %5.2lf °C" \
GPRINT:gmaxa:"Höchsttemperatur\: %5.2lf °C" \
GPRINT:g1a:"aktuelle Temperatur\: %5.2lf °C"

Netzwerkauslastung

Eine Auslastung der Netzwerkkarte fehlt noch. Diesmal wird für DS nicht GAUGE sondern COUNTER verwendet. Linux stellt einen die Daten als fortlaufende Zähler zur Verfügung und RRDTool kümmert sich dank der COUNTER Anweisung um den Rest.
root@pd6000:/auktion/rrdtool/temperatur # mkdir -p /auktion/rrdtool/network
root@pd6000:/auktion/rrdtool/temperatur # cd /auktion/rrdtool/network
root@pd6000:/auktion/rrdtool/network # /usr/local/rrdtool/bin/rrdtool create \
/auktion/rrdtool/network/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
Auch hier brauchen wir ein Script (/auktion/rrdtool/network/network.sh) zum Einlesen der Daten:
#!/bin/bash
AETH0=$(grep eth0 /proc/net/dev)
AE0DOWN=$(echo $AETH0|tr \: \ |awk '{print $2}')
AE0UP=$(echo $AETH0|tr \: \ |awk '{print $10}')
/usr/local/rrdtool/bin/rrdtool update /auktion/rrdtool/network/networketh0.rrd N:$AE0DOWN:$AE0UP
Im cron muß es auch eingetragen werden:
*/1 * * * *                     /auktion/rrdtool/network/network.sh
Einen Graphen wollen wir auch noch (wieder an /auktion/rrdtool/erzeugepng.sh anhängen):
nice -n 19 /usr/local/rrdtool/bin/rrdtool graph /auktion/apache/htdocs/monitoring/eth0.png --start -129600 \
-a PNG -t "Network Interface eth0" --vertical-label "Bytes/s" -w 600 -h 100 -M \
DEF:eth0r=/auktion/rrdtool/network/networketh0.rrd:eth0r:AVERAGE \
DEF:eth0t=/auktion/rrdtool/network/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
Neu sind hier die Anweisung COMMENT (wie der Name schon sagt, einfach nur ein Kommentar) und der Parameter %s beim GPRINT. %s sorgt dafür, das automatisch eine passende SI Einheit vorangestellt wird.
Wenn alles klappt, sollte so was rauskommen:

zurück zur Linux-Übersicht
Letzte Aktualisierung dieser Seite: 23. Februar 2007