RRDTool : base de données tournante dédiée à la supervision

RRDTool est un outil qui permet de faire des bases de données (Round-Robin Database). Il permet aussi de faire des graphes.

Dans ces bases de données on enregistre des informations telles que l'audience d'une radio en fonction de l'heure et du nombre d'auditeurs connectés simultanés

Nous allons pouvoir faire plusieurs choses avec les données :

- Affichage des données en fonction du temps (par exemple un graphe pour le jour en cours, pour la semaine, pour le mois et l'année).

- Si la radio a plusieurs canaux différents par exemple une radio avec de la musique uniquement et l'autre avec des animateurs on pourra combiner les données des deux stations sur le même graphe.

Il suffit d'installer le paquet rrdtool

Maintenant nous allons attaquer les choses sérieuses !

Cet exemple permet de créer une base de donnée RRD Tool pour deux radios.

Pour ce qui est de l'heure on convertit la date et l'heure actuelle en timestamp unix (nombre de secondes depuis le 1er janvier 1970 à 0h00:00)

Note pour connaitre le timestamp plusieurs solutions :

  • En ligne de commande
    $ date +%s
  • Sinon un petit plugin dans firefox qui se nomme : TimeStamp Converter est très pratique ;)

Nous allons créer une base RRD pour une Radio avec 2 flux : Rock et Alternative

   rrdtool create radios.rrd --start 1297810800 \
   DS:rock:GAUGE:600:U:U \
   DS:alternative:GAUGE:600:U:U \
   RRA:AVERAGE:0.5:1:24 \
   RRA:AVERAGE:0.5:6:12

Reprenons ligne par ligne le fonctionnement :

  • rrdtool create → jusque là tout va bien c'est pour dire qu'on créer une base de donnée RRD
  • radios.rrd → c'est le fichier rrd que nous utiliserons comme base de donnée
  • –start 1297810800 → indique la date de départ de ma base de donnée (en Timestamp) ici le 16 Février 2011 à 0h00.

La seconde et la 3eme ligne sont des DS (DATA SOURCE) sources de données en Français.

  • DS:ds-name:GAUGE | COUNTER | DERIVE | ABSOLUTE:heartbeat:min:max

Explications :

  • DS: → DATA SOURCE
  • ds-name → Nom de votre source de donnée (dans l'exemple rock) à savoir qu'elle doit faire entre 1 et 19 caracteres et alphanumérique avec possibilité d'utiliser "_" l'underscore soit [a-zA-Z0-9_]
  • GAUGE | COUNTER | DERIVE | ABSOLUTE → DST (DATA SOURCE TYPE)
  • COUNTER → valeurs incrémentales, ne diminue jamais sauf quand un compteur déborde. Si il dépasse 32 ou 64 bit.
  • GAUGE → valeurs entrées par l'utilisateur tel qu'une température ou autre…
  • DERIVE → valeurs positives ou négatives
  • ABSOLUTE → est pour les compteurs qui se réinitialisent à la lecture. Il est utilisé pour les compteurs de vitesse qui ont tendance à déborder.

Pour plus d'infos je vous renvoi à la doc http://oss.oetiker.ch/rrdtool/doc/rrdcreate.en.html

Passons à la 4eme et 5eme ligne qui sont les Round Robin Archives.

Une archive se compose d'un certain nombre de valeurs de données ou des statistiques pour chacune des sources de données définies (DS) et est définie par une ligne RRA.

  • RRA:AVERAGE | MIN | MAX | LAST:xff:steps:rows
  • RRA: → Round Robin Archive
  • AVERAGE → moyenne des valeurs
  • MIN → plus petite valeur enregistrée
  • MAX → plus grande valeur enregistrée
  • LAST → la derniere valeur enregistrée
  • 0.5 → frequence de lecture de la donnée (en secondes) soit ici l'équivalent de 5mn (600 * 0.5 = 300)
  • 1 → nombre de valeur pour faire la moyenne (ici 1 donc aucune moyenne)
  • 24 → nombre d'enregistrement que l'on souhaite conserver : 24 soit 2 heures (5mn x 24 = 2h00)

Idem pour la ligne suivante :

  • 0.5 → frequence de lecture de la donnée (en secondes) soit ici l'équivalent de 5mn (600 * 0.5 = 300)
  • 6 → nombre de valeur pour faire la moyenne (ici 6 donc une moyenne sur 6 enregistrements)
  • 12 → nombre d'enregistrement que l'on souhaite conserver : 12 soit 6 heures (la moyenne de 6 enregistrement : 6 x 5mn = 30mn ces 30mn x 12 = 6h00)
  rrdtool update radios.rrd    \
  1297810801:0:0    \
  1297811101:5:1    \
  1297811401:8:0    \
  1297811701:10:2	    \
  1297812001:13:3	    \
  1297812301:15:5	    \
  1297812601:23:4	    \
  1297812901:30:8	    \
  1297813201:34:9	    \
  1297813501:35:5	    \
  1297813801:38:10    \
  1297814101:38:12

A 0h00:01 il y avait 0 auditeur sur les deux flux. (timestamp:valeurflux1:valeurflux2)

A 0h05:01 il y avait 5 auditeurs sur le flux rock et 1 auditeur sur le flux alternative

Et on continue d'insérer les données grâce au timestamp toutes les 300 secondes (5mn)

A savoir : je ne peux pas enregistrer ma première donnée à 0h00:00 car lors de la création de notre RRD nous avons précisé qu'il commence à 0h00:00 il faut donc ajouter une seconde pour le 1er enregistrement. Sinon vous aurez une erreur de ce type : ERROR: radios.rrd: illegal attempt to update using time 1297810800 when last update time is 1297810800 (minimum one second step).

  rrdtool graph radios1.png -s 1297810800 -e 1297814101 -h 300 -w 600 -t "Graph d'audience" \
  DEF:rock=radios.rrd:rock:AVERAGE LINE3:rock#FF0000:"Rock" \
  DEF:alternative=radios.rrd:alternative:AVERAGE LINE3:alternative#000000:"Alternative"
  

Avec cette commande on affiche les données de notre base RRD dans un fichier png.

* -s → date (toujours en timestamp) de départ du graph pas forcement celle des données.

* -e → date de fin du graph pas forcement celle des données.

* -h → height hauteur du graph ici 300px

* -w → width largeur du graph ici 600px

* -t → titre du graphique

* DEF: → fetch les datas depuis le fichier rrd

* rock: → le nom de notre flux qu'on avait déjà défini (mais on peut en choisir un autre c'est un nom utilisé uniquement pour afficher la valeur)

* =radios.rrd → le nom de notre fichier rrd

* rock: → ici c'est le nom exact du Data Source

* AVERAGE → pour dire qu'on veut une moyenne

* LINE3:rock#FF0000:"Rock" → Pour afficher dans la légende notre valeur "rock" avec comme couleur rouge et comme label Rock.

Voilà pour l'instant vous savez : créer une base RRDTool, Updater les données de cette base et afficher un graphique.

Pour ceux qui souhaiteraient tenir à jour une base des données d'information sur leur système (testé sur Ubuntu 11.04 après installation du paquet RRDTool) voici un script qui crée deux sous répertoires dans le répertoire contenant ce script bash, l'un se remplira des bases de données l'autre des dernières images correspondantes. Il permet de créer une Round Robin Database pour :

  • le périphérique eth0
  • la charge système
  • la température du processeur
  • la mémoire vive

Il permet aussi d'alimenter ces bases de données par l'intermédiaire de la crontab de l'utilisateur puis de créer les graphes des 3 dernières heures d'activité et de les afficher dans eye of gnome.

#! /bin/bash
clear
cat << FIN
========= RRDTools Tool =========
Choisissez parmi ces modes :
a) Créer la base de données
z) Alimenter la base de données
e) Afficher le graphe
r) Quitter
=================================
FIN
date_immediate=$(date +%s)
Machine=$(echo "$HOSTNAME")
ICI=$(cd $(dirname "$0") && pwd)
doss_image="$ICI/Images/"
doss_rrd="$ICI/RRD/"
mkdir -p $doss_image
mkdir -p $doss_rrd

read touche
case "$touche" in
	a)		#création d'une RRD (fichier de base de donnée) pour log de trafic sur eth0 :
			#création d'une DataSource de type compteur pour le nombre d'octets reçus :
			#DS pour les octets transmis avec heartbeat (si passé ce délai,valeur=Unknown):borne mini:borne maxi (U==Unknown)	
			#RoundRobinArchive archives agrégeant les valeurs insérées dans la RRD.
			#RRA 0.5 proportion de PDP *Unknown* pas de 5 (*60s) pour 2016 fois : 2016*5*60=604800s==1 semaine
		clear
		echo "Choisissez une source parmi les suivantes :"
		echo "a) Trafic sur l'interfade eth0"
		echo "z) Température du processeur"
		echo "e) Utilisation CPU"
		echo "r) Utilisation mémoire"
		echo "t) Tous"
		read touche
	case "$touche" in
		a)
		nom=trafic_eth0
		nom_RRD=$doss_rrd$nom.rrd
		rrdtool create $nom_RRD -s 60 -b $date_immediate \
			DS:rx:COUNTER:120:0:U \
			DS:tx:COUNTER:120:0:U \
			RRA:LAST:0.5:1:1440 \
			RRA:AVERAGE:0.5:5:2016 
		echo "Création de la RDD $nom_RRD [OK]"
		;;
		z)
		nom=temperature
		nom_RRD=$doss_rrd$nom.rrd
		rrdtool create $nom_RRD -s 60 -b $date_immediate \
			DS:temp:GAUGE:120:0:U \
			RRA:MAX:0.5:1:1440 \
			RRA:MAX:0.5:10:1008 
		echo "Création de la RDD $nom_RRD [OK]"		
		;;
		e)
		nom=cpu
		nom_RRD=$doss_rrd$nom.rrd
		rrdtool create $nom_RRD -s 60 -b $date_immediate \
			DS:1min:GAUGE:150:0:U \
			DS:5min:GAUGE:150:0:U \
			DS:15min:GAUGE:150:0:U \
			RRA:AVERAGE:0.5:1:1440 \
			RRA:AVERAGE:0.5:10:1008 \
			RRA:AVERAGE:0.5:60:744 
		echo "Création de la RDD $nom_RRD [OK]"		
		;;
		r)
		nom=memoire
		nom_RRD=$doss_rrd$nom.rrd
		rrdtool create $nom_RRD -s 60 -b $date_immediate \
			DS:total:GAUGE:120:0:U \
			DS:free:GAUGE:120:0:U \
			RRA:LAST:0.5:1:1440 \
			RRA:AVERAGE:0.5:5:2016 
		echo "Création de la RDD $nom_RRD [OK]"		
		;;
		t)
		nom=trafic_eth0
		nom_RRD=$doss_rrd$nom.rrd
		rrdtool create $nom_RRD -s 60 -b $date_immediate \
			DS:rx:COUNTER:120:0:U \
			DS:tx:COUNTER:120:0:U \
			RRA:LAST:0.5:1:1440 \
			RRA:AVERAGE:0.5:5:2016 
		echo "Création de la RDD $nom_RRD [OK]"
		nom=temperature
		nom_RRD=$doss_rrd$nom.rrd
		rrdtool create $nom_RRD -s 60 -b $date_immediate \
			DS:temp:GAUGE:120:0:U \
			RRA:MAX:0.5:1:1440 \
			RRA:MAX:0.5:10:1008 
		echo "Création de la RDD $nom_RRD [OK]"	
		nom=cpu
		nom_RRD=$doss_rrd$nom.rrd
		rrdtool create $nom_RRD -s 60 -b $date_immediate \
			DS:1min:GAUGE:150:0:U \
			DS:5min:GAUGE:150:0:U \
			DS:15min:GAUGE:150:0:U \
			RRA:AVERAGE:0.5:1:1440 \
			RRA:AVERAGE:0.5:10:1008 \
			RRA:AVERAGE:0.5:60:744 
		echo "Création de la RDD $nom_RRD [OK]"	
		nom=memoire
		nom_RRD=$doss_rrd$nom.rrd
		rrdtool create $nom_RRD -s 60 -b $date_immediate \
			DS:total:GAUGE:120:0:U \
			DS:free:GAUGE:120:0:U \
			RRA:LAST:0.5:1:1440 \
			RRA:AVERAGE:0.5:5:2016 
		echo "Création de la RDD $nom_RRD [OK]"		
		;;
	esac
	;;

	z)
		#alimentation d'une RRD :
		clear
		echo "Choisissez une source parmi les suivantes :"
		echo "a) Trafic sur l'interfade eth0"
		echo "z) Température du processeur"
		echo "e) Utilisation CPU"
		echo "r) Utilisation mémoire"
		echo "t) Tous"
		echo "y) Effacer tout"
		read touche
		case "$touche" in
			a)
			nom=trafic_eth0
			nom_RRD=$doss_rrd$nom.rrd
crontab << FIN
$(crontab -l)
  * * * * *     rrdupdate $nom_RRD \$(grep eth0 /proc/net/dev | cut -d: -f2 | awk -v ts=\`date +\%s\` '{print ts":"\$1":"\$9}')
FIN
			;;
			z)
			nom=temperature
			nom_RRD=$doss_rrd$nom.rrd
crontab << FIN
$(crontab -l)
  * * * * *     rrdupdate $nom_RRD \$(echo "\$(cat /sys/class/thermal/thermal_zone0/temp)/1000" | bc | awk -v ts=\`date +\%s\` '{print ts":"\$1}')
FIN
			;;
			e)
			nom=cpu
			nom_RRD=$doss_rrd$nom.rrd
crontab << FIN
$(crontab -l)
  * * * * *     rrdupdate $nom_RRD \$(uptime | cut -d: -f5 | tr ',' ' ' | awk -v ts=\`date +\%s\` '{print ts":"\$1":"\$2":"\$3}')
FIN
			;;
			r)
			nom=memoire
			nom_RRD=$doss_rrd$nom.rrd
crontab << FIN
$(crontab -l)
  * * * * *     rrdupdate $nom_RRD \$(grep Mem /proc/meminfo | cut -d: -f2 | tr 'kB\n' ' ' | awk -v ts=\`date +\%s\` '{print ts":"\$1":"\$2}')
FIN
			;;
			t)
crontab << FIN
$(crontab -l)
  * * * * *     rrdupdate $(echo $doss_rrd)trafic_eth0.rrd \$(grep eth0 /proc/net/dev | cut -d: -f2 | awk -v ts=\`date +\%s\` '{print ts":"\$1":"\$9}') && rrdupdate $(echo $doss_rrd)temperature.rrd \$(echo "\$(cat /sys/class/thermal/thermal_zone0/temp)/1000" | bc | awk -v ts=\`date +\%s\` '{print ts":"\$1}') && rrdupdate $(echo $doss_rrd)cpu.rrd \$(uptime | cut -d: -f5 | tr ',' ' ' | awk -v ts=\`date +\%s\` '{print ts":"\$1":"\$2":"\$3}') && rrdupdate $(echo $doss_rrd)memoire.rrd \$(grep Mem /proc/meminfo | cut -d: -f2 | tr 'kB\n' ' ' | awk -v ts=\`date +\%s\` '{print ts":"\$1":"\$2}')
FIN
			;;
			y)
crontab << FIN
$(crontab -l | grep -v rrdupdate)
FIN
			;;
		esac
		echo "Création de la crontab [OK]"
		crontab -l
		;;
	
	e)

		#Affichage graphe
	        max_reception=8000000
	        max_emission=800000
		nom=trafic_eth0
		unite="B/s"
		vertical="Débit ($unite)"
		nom_RRD="$doss_rrd$nom.rrd"
		derniere_date=$(date +%A%_d\ %B\ %Y,\ %Hh%M -d @$(rrdtool last $nom_RRD))
		titre="Trafic eth0 ($derniere_date)"
		image="$doss_image$nom.png"
		echo "Création de l'image $nom :"
		rrdtool graph $image -v "$vertical" -w 800 -h 600 -E -s -3h -t "$titre" \
		DEF:rx=$nom_RRD:rx:LAST \
		DEF:tx=$nom_RRD:tx:LAST \
		HRULE:$max_reception#00aa55:"Maximum théorique réception ($max_reception $unite)\l" \
		HRULE:$max_emission#009922:"Maximum théorique émission ($max_emission $unite)\l" \
		COMMENT:"\r" \
		AREA:rx#00ff00:"RX" \
		GPRINT:rx:MAX:"\tMax\: %.2lf $unite" \
		GPRINT:rx:AVERAGE:"\tMoyenne\: %.2lf $unite\l" \
		AREA:tx#00aa00:"TX" \
		GPRINT:tx:MAX:"\tMax\: %.2lf $unite" \
		GPRINT:tx:AVERAGE:"\tMoyenne\: %.2lf $unite\l" \
		COMMENT:"Trafic de l'interface réseau sur $Machine\r"
#		eog $image 2>/dev/null &

		nom=temperature
		unite="°C"
		vertical="Température CPU ($unite)"
		nom_RRD=$doss_rrd$nom.rrd
		derniere_date=$(date +%A%_d\ %B\ %Y,\ %Hh%M -d @$(rrdtool last $nom_RRD))
		titre="Température ($derniere_date)"
		image="$doss_image$nom.png"
		echo "Création de l'image $nom :"
		rrdtool graph $image -v "$vertical" -w 800 -h 600 -E -s -3h -t "$titre" \
		DEF:temp=$nom_RRD:temp:MAX \
		AREA:temp#DD0000:"Température" \
		GPRINT:temp:MAX:"\tMax\: %.2lf $unite" \
		GPRINT:temp:AVERAGE:"\tMoyenne\: %.2lf $unite\j" \
		HRULE:60#aa0000:"avertissement\l" \
		HRULE:70#550000:"alerte\l" \
		COMMENT:"Température CPU sur $Machine\r"
#		eog $image 2>/dev/null &
		
		nom=cpu
		unite=""
		vertical="Load average"
		nom_RRD=$doss_rrd$nom.rrd
		derniere_date=$(date +%A%_d\ %B\ %Y,\ %Hh%M -d @$(rrdtool last $nom_RRD))
		titre="Charge système ($derniere_date)"
		image="$doss_image$nom.png"
		CPU=$(grep "model name" /proc/cpuinfo | cut -d: -f2)
		echo "Création de l'image $nom :"
		rrdtool graph $image -v "$vertical" -w 800 -h 600 -E -s -3h -t "$titre" \
		DEF:1mn=$nom_RRD:1min:AVERAGE \
		DEF:5mn=$nom_RRD:5min:AVERAGE \
		DEF:15mn=$nom_RRD:15min:AVERAGE \
		AREA:1mn#00c9e4:"1 min" \
		GPRINT:1mn:MAX:"\tMax\: %.2lf $unite" \
		GPRINT:1mn:AVERAGE:"\tMoyenne\: %.2lf $unite\j" \
		AREA:5mn#0097a0:"5 min" \
		GPRINT:5mn:MAX:"\tMax\: %.2lf $unite" \
		GPRINT:5mn:AVERAGE:"\tMoyenne\: %.2lf $unite\j" \
		AREA:15mn#003d4f:"15 min" \
		GPRINT:15mn:MAX:"\tMax\: %.2lf $unite" \
		GPRINT:15mn:AVERAGE:"\tMoyenne\: %.2lf $unite\j" \
		HRULE:0.5#ffb921:"avertissement\l" \
		HRULE:1#ff0000:"alerte\l" \
		COMMENT:"Charge système \: $CPU sur $Machine\r"
#		eog $image 2>/dev/null &
		
		nom=memoire
		unite="kB"
		vertical="quantité de mémoire ($unite)"
		nom_RRD=$doss_rrd$nom.rrd
		derniere_date=$(date +%A%_d\ %B\ %Y,\ %Hh%M -d @$(rrdtool last $nom_RRD))
		titre="Mémoire RAM ($derniere_date)"
		image="$doss_image$nom.png"
		echo "Création de l'image $nom :"
		rrdtool graph $image -v "$vertical" -w 800 -h 600 -E -s -3h -t "$titre" \
		DEF:total=$nom_RRD:total:LAST \
		DEF:free=$nom_RRD:free:LAST \
		AREA:total#c8ad7f:"Mem. totale" \
		GPRINT:total:MAX:"\tMax\: %.2lf $unite" \
		GPRINT:total:AVERAGE:"\tMoyenne\: %.2lf $unite\l" \
		AREA:free#f0c300:"Mem. libre " \
		GPRINT:free:MAX:"\tMax\: %.2lf $unite" \
		GPRINT:free:AVERAGE:"\tMoyenne\: %.2lf $unite\l" \
		COMMENT:"\r" \
		COMMENT:"Utilisation de la mémoire par le système sur $Machine\r"
		eog $image 2>/dev/null &
	;;
	r)
		exit
	;;
esac
echo "Appuyez sur une touche pour revenir au menu principal."
read touche
killall eog
bash $0

Il est possible qu'une adaptation/réécriture soit nécessaire chez vous, notamment pour la collecte des infos du système. Cela peut être une base pour administrer sa machine à distance; on peut le compléter avec un serveur léger de page web affichant les images comme sur la "freebox révolution".


Contributeurs : ChoiZ anotherubuntuuser

  • rrdtool.txt
  • Dernière modification: Le 14/05/2014, 06:21
  • (modification externe)