1 - Préambule
Dans l'article précédent Freebox Revolution sur Cacti Méthode simple nous avons vu comment interroger la Freebox et grapher la dernière valeur des données reçues. Nous allons voir maintenant comment grapher toutes les valeurs des données reçues.
2 - Contexte
Le programme d'interrogation doit être modifié pour traiter toutes les valeurs mais Cacti ne nous donne pas la possibilité d'enregistrer toutes ces valeurs. Le programme d'interrogation devra donc enregistrer lui-même les valeurs dans le fichier RRD utilisé par Cacti, puis nous dirons à Cacti d'afficher le graphique à partir de ce fichier RRD.
3 - Programme d'interrogation
Voici les étapes que j'ai défini pour pouvoir enregistrer les données.
- test existence fichier rrd : oui=récupération time dernière écriture, non=création du fichier
- authentifcation sur la Freebox
- interrogation et sauvegarde des données
- travail sur tx_1 et création d'un fichier pour enregistrement dans RRD
- travail sur tx_2 et modification du fichier pour enregistrement dans RRD
- travail sur tx_3 et modification du fichier pour enregistrement dans RRD
- travail sur tx_4 et modification du fichier pour enregistrement dans RRD
- si ce fichier existe alors enregistrement dans RRD et suppression de ce fichier
3.1 - Test existence fichier RRD
#!/bin/sh clear # Variables rra_path="/srv/eyesofnetwork/cacti-0.8.8a/rra/" # check freebox_tx.rrd if [ -f $rra_path"freebox_tx.rrd" ] then last_update=`/usr/bin/rrdtool last $rra_path"freebox_tx.rrd"` else /usr/bin/rrdtool create /srv/eyesofnetwork/cacti-0.8.8a/rra/freebox_tx.rrd --step 60 DS:tx_4:GAUGE:600:U:U DS:tx_3:GAUGE:600:U:U DS:tx_2:GAUGE:600:U:U DS:tx_1:GAUGE:600:U:U RRA:AVERAGE:0.5:1:500 RRA:AVERAGE:0.5:1:600 RRA:AVERAGE:0.5:6:700 RRA:AVERAGE:0.5:24:775 RRA:AVERAGE:0.5:288:797 RRA:MAX:0.5:1:500 RRA:MAX:0.5:1:600 RRA:MAX:0.5:6:700 RRA:MAX:0.5:24:775 RRA:MAX:0.5:288:797 fi echo $last_update;
La variable rra_path est à adapter selon votre installation. Le RRD crée utilisera les valeurs tx_1 à tx_4. La ligne de commande a été relevé dans les logs de Cacti.
3.2 - Authentification sur la Freebox
app_token=`grep "app_token" "/tmp/post_authorize.log" | cut -f 4 -d ':' | cut -f 1 -d ','| sed 's/\\\//g' |sed "s/\"//g"| sed "s/\r//g" | sed "s/\n//g"` curl -H "Content-type: application/json" -X GET http://mafreebox.freebox.fr/api/v1/login/>/tmp/challenge.log 2>/dev/null challenge=`grep "challenge" "/tmp/challenge.log" | cut -f 5 -d ':' | cut -f 1 -d ','| sed 's/\\\//g' |sed "s/\"//g"| sed "s/\r//g" | sed "s/\n//g"` password=`echo -n $challenge | openssl dgst -sha1 -hmac $app_token` curl -i -H "Content-type: application/json" -X POST http://mafreebox.freebox.fr/api/v1/login/session/ -d ' { "app_id": "fr.prestaopen.cacti", "password": "'$password'" } '>/tmp/session_token.log 2>/dev/null session_token=`grep "session_token" "/tmp/session_token.log" | cut -f 3 -d ':' | cut -f 1 -d ','| sed 's/\\\//g' |sed "s/\"//g"| sed "s/\r//g" | sed "s/\n//g"`
Cette partie du code découle de cet article : Freebox Revolution Scripts
3.3 - Interrogation et sauvegarde des données
curl -i -X POST http://mafreebox.freebox.fr/api/v1/rrd/ -H "X-Fbx-App-Auth: $session_token" -d ' { "db": "switch", "fields": [ "tx_1" ], "precision": 1 } '> /tmp/switch_tx_1.log 2>/dev/null curl -i -X POST http://mafreebox.freebox.fr/api/v1/rrd/ -H "X-Fbx-App-Auth: $session_token" -d ' { "db": "switch", "fields": [ "tx_2" ], "precision": 1 } '> /tmp/switch_tx_2.log 2>/dev/null curl -i -X POST http://mafreebox.freebox.fr/api/v1/rrd/ -H "X-Fbx-App-Auth: $session_token" -d ' { "db": "switch", "fields": [ "tx_3" ], "precision": 1 } '> /tmp/switch_tx_3.log 2>/dev/null curl -i -X POST http://mafreebox.freebox.fr/api/v1/rrd/ -H "X-Fbx-App-Auth: $session_token" -d ' { "db": "switch", "fields": [ "tx_4" ], "precision": 1 } '> /tmp/switch_tx_4.log 2>/dev/null
Cette partie du code découle de cet article : Freebox Revolution Scripts
3.4 - Travail sur tx_1 et création d'un fichier pour enregistrement dans RRD
for ligne in `cat /tmp/switch_tx_1.log`; do echo $ligne >null done #echo $ligne # Découpage en ligne tx1:time for i in `echo $ligne | tr "{" " "`; do #echo $i; k=1 # test 1ere ligne if [[ "$i" =~ "true" ]] ; then echo "ligne 1" # test 2eme ligne elif [[ "$i" =~ "date_start" ]]; then echo "Ligne 2" # sinon autres lignes else for j in `echo $i | tr ',' ' '`; do if test $k == 1 then value_time=`echo $j | grep -oE "[^:]+$"`; #echo $value_time k=2; else value_data=`echo $j | grep -oE "[^:]+$" | sed 's/\([0-9]*\).*/\1/'`; #echo $value_data k=1; if test $value_time -gt $last_update then k=1; #echo $last_update."ecriture".$value_time #echo $value_time:$value_data echo $value_time:$value_data >> "/tmp/freebox_tx.log" #/usr/bin/rrdtool update $rra_path"freebox_tx.rrd" --template tx_1:tx_2:tx_3:tx_4 $value_time:0:0:$value_data:0 else k=1; #echo $value_time." plus ancien que ".$last_update fi fi done fi done
Le fichier reçu est sous la forme :
HTTP/1.1 200 OK Server: nginx Date: Wed, 28 Aug 2013 09:00:19 GMT Content-Type: application/json; charset=utf-8 Transfer-Encoding: chunked Connection: keep-alive {"success":true,"result":{"date_start":1377658800,"data":[{"time":1377658800,"tx_1":0},{"time":1377658920,"tx_1":0},{"time":1377659040,"tx_1":0},{"time":1377659160,"tx_1":0},{"time":1377659280,"tx_1":0},{"time":1377659400,"tx_1":0},{"time":1377659520,"tx_1":0},{"time":1377659640,"tx_1":0},{"time":1377659760,"tx_1":0},{"time":1377659880,"tx_1":0},{"time":1377660000,"tx_1":0},{"time":1377660120,"tx_1":0 ................... {"time":1377680040,"tx_1":0},"time":1377680160,"tx_1":0},"time":1377680280,"tx_1":0}],"date_end":1377680400}}
On ne garde que la dernière ligne :
{"success":true,"result":{"date_start":1377658800,"data":[{"time":1377658800,"tx_1":0},{"time":1377658920,"tx_1":0},{"time":1377659040,"tx_1":0},{"time":1377659160,"tx_1":0},{"time":1377659280,"tx_1":0},{"time":1377659400,"tx_1":0},{"time":1377659520,"tx_1":0},{"time":1377659640,"tx_1":0},{"time":1377659760,"tx_1":0},{"time":1377659880,"tx_1":0},{"time":1377660000,"tx_1":0},{"time":1377660120,"tx_1":0 ................... {"time":1377680040,"tx_1":0},"time":1377680160,"tx_1":0},"time":1377680280,"tx_1":0}],"date_end":1377680400}}
On découpe cette ligne en sous-lignes par la commande :
`echo $ligne | tr "{" " "`;
pour obtenir :
"success":true,"result": "date_start":1377658800,"data":[ "time":1377658800,"tx_1":0}, "time":1377658920,"tx_1":0}, "time":1377659040,"tx_1":0}, "time":1377659160,"tx_1":0}, ................... "time":1377680040,"tx_1":0}, "time":1377680160,"tx_1":0}, "time":1377680280,"tx_1":0}],"date_end":1377680400}}
On ne tient pas compte des 2 premières lignes et on récupère les valeurs sous la forme time:tx_1.
Si la valeur time et supérieure à la valeur de la dernière écriture, alors on crée un fichier sous la forme :
1377681000:0 1377681120:0
3.5 - Travail sur tx_2 et modification du fichier pour enregistrement dans RRD
for ligne in `cat /tmp/switch_tx_2.log`; do echo $ligne >null done #echo $ligne # Découpage en ligne tx3:time for i in `echo $ligne | tr "{" " "`; do #echo $i; k=1 # test 1ere ligne if [[ "$i" =~ "true" ]] ; then echo "ligne 1" # test 2eme ligne elif [[ "$i" =~ "date_start" ]]; then echo "Ligne 2" # sinon autres lignes else for j in `echo $i | tr ',' ' '`; do if test $k == 1 then value_data=`echo $j | grep -oE "[^:]+$"`; #echo $value_data k=2; else value_time=`echo $j | grep -oE "[^:]+$" | sed 's/\([0-9]*\).*/\1/'`; #value_time=`echo $j | grep -oE "[^:]+$"| sed 's/.\{1\}$//'`; #echo $value_time k=1; if test $value_time -gt $last_update then k=1; #num_ligne=`grep -n $value_time /tmp/freebox_tx.log | cut -d: -f1` #echo $last_update."ecriture".$value_time #echo $num_ligne #echo $value_data sed -e "s/$value_time.*/&:$value_data/g" -i /tmp/freebox_tx.log #/usr/bin/rrdtool update $rra_path"freebox_tx.rrd" --template tx_1:tx_2:tx_3:tx_4 $value_time:0:0:$value_data:0 else k=1; #echo $value_time." plus ancien que ".$last_update fi fi done fi done
Le travail sur les valeurs de tx_2 est identique sauf que les données sont sous la forme tx_2:time.
On teste aussi la valeur de time par rapport à la valeur du dernier enregistrement, pour parcourir le fichier freebox_tx.log et le compléter si la valeur de time y est incluse. Cela donne au final pour freebox_tx.log :
1377681000:0:0 1377681120:0:0 1377681240:0:0 1377681360:0:0 1377681480:0:0
3.6 - Travail sur tx_3 et modification du fichier pour enregistrement dans RRD
for ligne in `cat /tmp/switch_tx_3.log`; do echo $ligne >null done #echo $ligne # Découpage en ligne tx3:time for i in `echo $ligne | tr "{" " "`; do #echo $i; k=1 # test 1ere ligne if [[ "$i" =~ "true" ]] ; then echo "ligne 1" # test 2eme ligne elif [[ "$i" =~ "date_start" ]]; then echo "Ligne 2" # sinon autres lignes else for j in `echo $i | tr ',' ' '`; do if test $k == 1 then value_data=`echo $j | grep -oE "[^:]+$"`; #echo $value_data k=2; else value_time=`echo $j | grep -oE "[^:]+$" | sed 's/\([0-9]*\).*/\1/'`; #value_time=`echo $j | grep -oE "[^:]+$"| sed 's/.\{1\}$//'`; #echo $value_time k=1; if test $value_time -gt $last_update then k=1; #num_ligne=`grep -n $value_time /tmp/freebox_tx.log | cut -d: -f1` #echo $last_update."ecriture".$value_time #echo $num_ligne #echo $value_data sed -e "s/$value_time.*/&:$value_data/g" -i /tmp/freebox_tx.log #/usr/bin/rrdtool update $rra_path"freebox_tx.rrd" --template tx_1:tx_2:tx_3:tx_4 $value_time:0:0:$value_data:0 else k=1; #echo $value_time." plus ancien que ".$last_update fi fi done fi done
Le travail sur les valeurs de tx_3 est identique sauf que les données sont sous la forme tx_3:time.
On teste aussi la valeur de time par rapport à la valeur du dernier enregistrement, pour parcourir le fichier freebox_tx.log et le compléter si la valeur de time y est incluse. Cela donne au final pour freebox_tx.log :
1377681000:0:0:329547 1377681120:0:0:330120 1377681240:0:0:329058 1377681360:0:0:330181 1377681480:0:0:330076 1377681600:0:0:329489
3.7 - Travail sur tx_4 et modification du fichier pour enregistrement dans RRD
for ligne in `cat /tmp/switch_tx_4.log`; do echo $ligne >null done #echo $ligne # Découpage en ligne tx1:time for i in `echo $ligne | tr "{" " "`; do #echo $i; k=1 # test 1ere ligne if [[ "$i" =~ "true" ]] ; then echo "ligne 1" # test 2eme ligne elif [[ "$i" =~ "date_start" ]]; then echo "Ligne 2" # sinon autres lignes else for j in `echo $i | tr ',' ' '`; do if test $k == 1 then value_time=`echo $j | grep -oE "[^:]+$"`; #echo $value_time k=2; else value_data=`echo $j | grep -oE "[^:]+$" | sed 's/\([0-9]*\).*/\1/'`; #echo $value_data k=1; if test $value_time -gt $last_update then k=1; #num_ligne=`grep -n $value_time /tmp/freebox_tx.log | cut -d: -f1` #echo $last_update."ecriture".$value_time #echo $num_ligne #echo $value_data sed -e "s/$value_time.*/&:$value_data/g" -i /tmp/freebox_tx.log #/usr/bin/rrdtool update $rra_path"freebox_tx.rrd" --template tx_1:tx_2:tx_3:tx_4 $value_time:0:0:$value_data:0 else k=1; #echo $value_time." plus ancien que ".$last_update fi fi done fi done
Le travail sur les valeurs de tx_4 est identique sauf que les données sont sous la forme time:tx_4.
On teste aussi la valeur de time par rapport à la valeur du dernier enregistrement, pour parcourir le fichier freebox_tx.log et le compléter si la valeur de time y est incluse. Cela donne au final pour freebox_tx.log :
1377681000:0:0:329547:318522 1377681120:0:0:330120:318443 1377681240:0:0:329058:318427 1377681360:0:0:330181:318436 1377681480:0:0:330076:317609 1377681600:0:0:329489:318434 1377681720:0:0:330260:318478 1377681840:0:0:329597:318424
3.8 - Si ce fichier existe alors enregistrement dans RRD et suppression de ce fichier
if [ -f "/tmp/freebox_tx.log" ] then for ligne in `cat /tmp/freebox_tx.log`; do echo $ligne /usr/bin/rrdtool update $rra_path"freebox_tx.rrd" --template tx_1:tx_2:tx_3:tx_4 $ligne done rm -f /tmp/freebox_tx.log fi
Maintenant que le script est en place, nous allons voir comment configurer Cacti pour utiliser ce script et afficher le graphique à partir de notre fichier RRD.
4 - Data Input Method
5 - Data Template
6 - Data Source
7 - Graph Template
Nous allons seulement détaillé les items 9 à 12. Pour les autres il suffit de s'en inspirer.
8 - Résultat
Après avoir assigné ce template à la Freebox, nous obtenons ceci :
au lieu de :
Le nouveau graphique est plus précis dans le temps.
9 - Conclusion
Si l'on me demande si il est nécessaire de produire des graphiques de ma Freebox, je répondrai non. L'interface de mafreebox.freebox.fr nous donne tous les graphiques voulus. Alors pourquoi ces articles sur www.prestaopen.com ?
Ces articles nous ont permis de voir:
- la possibilité de se connecter à l'API de la Freebox et de récupérer des informations
- la possibilité avec bash de scripter cette récupération de renseigner un fichier RRD avec plusieurs cycles de données
- la possibilité de lancer ce script depuis Cacti
- la possibilité de produire un graphique avec un fichier RRD généré par ailleurs.
J'espère que vous avez pris du plaisir à me lire, cette série d'article est perfectible, n'hésitez pas à me laisser vos commentaires.