Le logiciel rrdtool permet de générer des graphes avec une base de données remplie au fil du temps. L'interêt est qu'il dispose d'une méthode pour que sa base de données conserve sa taille quel que soit la durée d'execution. RRD est l'acronyme de Round Robbin Database.
Compilation de rrdcollect
Le logiciel rrdcollect permet d'automatiser le remplissage des bases de données de rrdtool. Cependant il n'est pas empaqueté pour Debian stable, il faut donc le compiler.
Les bibliothèques librrd0-dev et libpcre3-dev sont nécessaires à la compilation :
apt-get install librrd0-dev librrd0-dev
Une fois l'archive de rrdcollect téléchargée, il faut le compiler :
tar xvzf rrdcollect-0.2.3.tar.gz
cd rrdcollect-0.2.3/
dpkg-buildpackage
Le fichier rrdcollect_0.2.1-3_i386.deb est créé dans le répertoire superieur. Ce paquet sera installé sur toutes les machines à monitorer.
Le fichier de configuration /etc/rrdcollect.conf sert à définir les commande à lancer pour determiner les données à enregister. Ici on analyse la charge CPU et mémoire toutes les 60 secondes:
step = 60
directory = /root/rrd
file:/*proc/meminfo
/^MemTotal:\s*(\d+) kB/ mem.rrd:mem_total
/^MemFree:\s*(\d+) kB/ mem.rrd:mem_free
file:/*proc/stat
/^cpu\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)/ cpu.rrd:cpu_user,cpu_nice,cpu_system,cpu_idle,cpu_iowait,cpu_irq,cpu_softirq
Création des bases
Le script /root/rrd/create.sh permet de créer les bases pour monitorer le CPU et la mémoire :
#!/bin/bash
RRDPATH=/root/rrd
rrdtool create $RRDPATH/mem.rrd \
--start `date +%s` \
--step 60 \
DS:mem_total:GAUGE:150:0:U \
DS:mem_free:GAUGE:150:0:U \
RRA:AVERAGE:0.5:1:1440 \
RRA:AVERAGE:0.5:10:1008 \
RRA:AVERAGE:0.5:60:744
rrdtool create $RRDPATH/cpu.rrd \
--start `date +%s` \
--step 60 \
DS:cpu_user:COUNTER:150:0:100 \
DS:cpu_nice:COUNTER:150:0:100 \
DS:cpu_system:COUNTER:150:0:100 \
DS:cpu_idle:COUNTER:150:0:100 \
DS:cpu_iowait:COUNTER:150:0:100 \
DS:cpu_irq:COUNTER:150:0:100 \
DS:cpu_softirq:COUNTER:150:0:100 \
RRA:AVERAGE:0.5:1:1440 \
RRA:AVERAGE:0.5:10:1008 \
RRA:AVERAGE:0.5:60:744
- la ligne RRA:AVERAGE:0.5:1:1440 signifie qu'on fait la moyenne (AVERAGE:0.5) sur 1 échantillon et qu'on en garde 1440 exemplaires (1440 = 60 * 24). On garde tous les relevés pendant une journée.
- la ligne RRA:AVERAGE:0.5:10:1008 signifie qu'on fait la moyenne (AVERAGE:0.5) sur 10 échantillons et qu'on en garde 1008 exemplaires (1008 = ( 60 * 24 * 7) / 10). On fait une moyenne toutes les 10 minutes et on les garde pendant 7 jours.
- la ligne RRA:AVERAGE:0.5:60:744 signifie qu'on fait la moyenne (AVERAGE:0.5) sur 60 échantillons et qu'on en garde 744 exemplaires ( 744 = ( 60 * 24 * 31 ) / 60). On fait la moyenne toutes les heures et on les gardes pendant 1 mois.
Génération des graphes
Les graphes sont stockés dans le répertoire du site web. Le script qui les créé est /root/rrd/graph.sh :
#!/bin/bash
RRDPATH=/root/rrd
WEBPATH=/var/www/rrd
MEM_LIM="4.5e+09"
MEM_LBL="4Go"
MEM_HR="4.29e+09"
rrdtool graph $WEBPATH/mem-3h.png \
--title 'Memoire utilisée sur 3 heures' \
--start -3h --end now \
--base 1024 \
--upper-limit $MEM_LIM --lower-limit 0 -r \
DEF:mem_total=$RRDPATH/mem.rrd:mem_total:AVERAGE \
DEF:mem_free=$RRDPATH/mem.rrd:mem_free:AVERAGE \
CDEF:mem_used=mem_total,mem_free,-,1024,* \
'AREA:mem_used#00FF00:M\xe9moire utilis\xe9e' \
HRULE:$MEM_HR'#FF0000:Limite \: '$MEM_LBL
rrdtool graph $WEBPATH/cpu-3h.png -o \
--title 'Charge CPU sur 3 heures' \
--start -3h --end now \
DEF:cpu_user=$RRDPATH/cpu.rrd:cpu_user:AVERAGE \
DEF:cpu_nice=$RRDPATH/cpu.rrd:cpu_nice:AVERAGE \
DEF:cpu_system=$RRDPATH/cpu.rrd:cpu_system:AVERAGE \
DEF:cpu_idle=$RRDPATH/cpu.rrd:cpu_idle:AVERAGE \
DEF:cpu_iowait=$RRDPATH/cpu.rrd:cpu_iowait:AVERAGE \
DEF:cpu_irq=$RRDPATH/cpu.rrd:cpu_irq:AVERAGE \
DEF:cpu_softirq=$RRDPATH/cpu.rrd:cpu_softirq:AVERAGE \
'AREA:cpu_iowait#0000FF:IO wait' \
'STACK:cpu_system#FF9999:system' \
'STACK:cpu_nice#FF99FF:nice' \
'STACK:cpu_user#99FF99:user' \
'STACK:cpu_idle#FFFFFF:idle'
rrdtool graph $WEBPATH/mem-7d.png \
--title 'Memoire utilisée sur 7 jours' \
--start -7d --end now \
--base 1024 \
--upper-limit $MEM_LIM --lower-limit 0 -r \
DEF:mem_total=$RRDPATH/mem.rrd:mem_total:AVERAGE \
DEF:mem_free=$RRDPATH/mem.rrd:mem_free:AVERAGE \
CDEF:mem_used=mem_total,mem_free,-,1024,* \
'AREA:mem_used#00FF00:Memoire utilisée' \
HRULE:$MEM_HR'#FF0000:Limite \: '$MEM_LBL
rrdtool graph $WEBPATH/cpu-7d.png -o \
--title 'Charge CPU sur 7 jours' \
--start -7d --end now \
DEF:cpu_user=$RRDPATH/cpu.rrd:cpu_user:AVERAGE \
DEF:cpu_nice=$RRDPATH/cpu.rrd:cpu_nice:AVERAGE \
DEF:cpu_system=$RRDPATH/cpu.rrd:cpu_system:AVERAGE \
DEF:cpu_idle=$RRDPATH/cpu.rrd:cpu_idle:AVERAGE \
DEF:cpu_iowait=$RRDPATH/cpu.rrd:cpu_iowait:AVERAGE \
DEF:cpu_irq=$RRDPATH/cpu.rrd:cpu_irq:AVERAGE \
DEF:cpu_softirq=$RRDPATH/cpu.rrd:cpu_softirq:AVERAGE \
'AREA:cpu_iowait#0000FF:IO wait' \
'STACK:cpu_system#FF9999:system' \
'STACK:cpu_nice#FF99FF:nice' \
'STACK:cpu_user#99FF99:user' \
'STACK:cpu_idle#FFFFFF:idle'
Lancement des scripts
Le script de démarrage fournit par la compilation de rrdcollect (/etc/init.d/rrdcollect) n'est pas fonctionnel, il faut le remplacer par celui-ci :
#! /bin/sh
PATH=/sbin:/bin:/usr/sbin:/usr/bin
DAEMON=/usr/sbin/rrdcollect
NAME=rrdcollect
DESC=rrdcollect
test -f $DAEMON || exit 0
set -e
case "$1" in
start)
echo "Starting $DESC: $NAME"
start-stop-daemon --start --quiet --make-pidfile --pidfile /var/run/$NAME.pid \
--background --exec $DAEMON -- -n
;;
stop)
echo "Stopping $DESC: $NAME"
start-stop-daemon --oknodo --stop --quiet --pidfile /var/run/$NAME.pid \
--exec $DAEMON
;;
restart|force-reload)
echo "Restarting $DESC: $NAME"
start-stop-daemon --oknodo --stop --quiet --pidfile /var/run/$NAME.pid \
--exec $DAEMON
sleep 1
start-stop-daemon --start --quiet --make-pidfile --pidfile /var/run/$NAME.pid \
--background --exec $DAEMON -- -n
;;
*)
N=/etc/init.d/$NAME
echo "Usage: $N {start|stop|restart|force-reload}" >&2
exit 1
;;
esac
exit 0
Le script qui calcul l'espace disque occupé par les utilisateurs est à placer dans /root/espace-disque/calcul.sh :
#!/bin/bash
SILENT=true
cd /root/espace-disque/
[ $SILENT = "true" ] || echo "Calcul de l'espace occupe..."
du -h -s /home/* > resume
sort -n resume > /var/www/resume-tri
Ensuite il faut lancer la création de graphe automatiquement. Pour ne pas surcharger la machine, on va regénérer les graphes toutes les 5 minutes en utilisant la crontab :
*/5 * * * * /root/rrd/graph.sh
0 12 * * 0 /root/espace-disque/calcul.sh
Apache
Le serveur Apache va afficher toutes les informations que l'on va collecter. On souhaite avoir une page qui donne les informations sur l'état de la machine. L'application [http://phpsysinfo.sourceforge.net|phpsysinfo] donne un apercu des ressources systèmes :
apt-get install phpsysinfo
La page d'accueil est à placer dans /var/www/index.html :
<html>
<head>
<title>Monitoring de la machine</title>
</head>
<body>
<div>
<h1>Monitoring de la machine</h1>
<ul>
<li><a href="phpsysinfo/">phpsysinfo</a></li>
<li><a href="rrd.html">Charge système</a></li>
<li><a href="disque.php">Espace disque</a></li>
</ul>
</div>
</body>
</html>
Le fichier /var/www/rrd.html contient les images générées automatiquement :
<html>
<head>
<title>Charge système</title>
</head>
<body>
<div>
<h1>Charge système</h1>
<h2>Charge CPU sur 3 heures</h2>
<p><img src="rrd/cpu-3h.png" alt="Charge CPU sur 3 heures"/></p>
<h2>Charge mémoire sur 3 heures</h2>
<p><img src="rrd/mem-3h.png" alt="Charge mémoire sur 3 heures"/></p>
<h2>Charge CPU sur 7 jours</h2>
<p><img src="rrd/cpu-7d.png" alt="Charge CPU sur 7 jours"/></p>
<h2>Charge mémoire sur 7 jours</h2>
<p><img src="rrd/mem-7d.png" alt="Charge mémoire sur 7 jours"/></p>
</div>
</body>
</html>
Le fichier /var/www/disque.php contient la liste des utilisateurs prenant plus de 500Mo d'espace disque :
<?php
echo "<html>
<head>
<title>Consommation d'espace disque</title>
<meta http-equiv="Refresh" content="300"/>
<meta http-equiv="Pragma" content="no-cache"/>
</head>
<body>
<div>
<h1>Consommation d'espace disque</h1>
<p>Liste des utilisateurs prenant plus de 500Mo d'espace disque.</p>
<ul>";
$path = 'resume-tri';
$fichier = @file( $path );
if ( $fichier == null ) {
exit();
}
reset($fichier);
foreach ( $fichier as $line ) {
$line = rtrim( $line );
$line = ltrim( $line );
if ($line == "" || $line == "\n" || strstr( $line, "#" ) ) {
next($config);
}
else {
# recupere les compte qui ont plus d'1Go
# (taille) (unite) (chemin)
preg_match( "/(\d+\.?\d+)([G])\s*(.*)/", $line, $res );
if ( strlen( $res[0] ) != 0 ) {
list( , , ,$uid ) = explode( '/', $res[3] );
echo "<li>$uid consomme " . $res[1] . $res[2] . "</li>\n";
}
}
}
echo "</ul>
</div>
</body>
</html>";
?>