Moniteur en SVG avec javascript et données en server-push
-
© 2008 Félix Hauri -
EMail -
Web
Toutes les informations sur ces pages sont publiées sous les termes de la license LGPL v2.1
Ce système utilise des standard publiés. Il fonctionne sans greffons additionnels dans une version récente de FireFox
Il ne fonctionne malheureusement pas sous Microsoft Internet Explorer, mais ce n'est pas moi que cela va contrarier... Microsoft n'a qu'à respecter les standards. Il s'agit d'un essai (prototype) avec pour but de- utiliser le moins de bande passante en faisant passer un minimum de données (moins de 100 octets par secondes)
- consomer le moins de ressources possible, sur le serveur
- obtenir des graphiques agréables du coté client
- avoir un maximum d'informations, du coté client
- créer des outils de monitoring intéractifs
- déléguer les tâches de programmation et de réalisation graphiques à des personnes différentes
- Premier essai: Le moniteur CPU Les deux seules informations transmises périodiquement sont UPTIME (Le temps écoulé depuis que l'ordinateur est allumé) et IDLETIME (Le temps écoulé pendant lequel le processeur est resté inactif). Le script connait l'heure à laquelle l'ordinateur à démarré (wasup), ainsi il peut calculer la totalité du temps de travail, la quantité de temps de travail depuis le dernier intervalle et l'heure interne du serveur (wasup + UPTIME). Le dessin à été réalisé ``vite-fait'' avec skencil et sodipodi. La documentation pour javascript/ecmascript à été trouvée à: Core JavaScript 1.5 Reference - Mozilla Developer Center
-
Moniteur CPU - Mode d'emploi:
Le moniteur affiche le travail du processeur en %, toutes les
secondes, avec une aiguille blanche.
La valeur correspondante s'affiche en haut du cadran.
Une aiguille bleue affiche la moyenne sur 5 minutes (moyenne du graphique en dessous).
Une aiguille violette affiche la moyenne absolue depuis que l'ordinateur à été mis sous tension. Afin d'économiser les ressources sur le poste client, le graphique peut être masqué. Il suffit de cliquer dessus pour le faire disparaitre et ainsi réduire la consomation du navigateur web (les données sont toujours mémorisées).
Un click sur le logo le fera ré-apparaitre et mettre à jour. Le cadran présente un bouton ``S'' pour Snapshot qui permet de placer un repère temporel à partir duquel le moniteur calculera la moyenne. A chaque pression sur ce bouton, le moniteur positionnera ou repositionnera son repère temporel.
Un bouton ``R'' permet de supprimer le Snap pour afficher à nouveau l'aiguille violette représentant la moyenne totale. -
Voici le script perl qui envoie périodiquement les données.
#!/usr/bin/perl -w use strict; use CGI qw/:standard :push -nph/; my $q=CGI->new; $| = 1; open FH,"</proc/uptime"; sub readprocuptime { seek FH,0,0; return <FH>; } print multipart_init(-boundary=>'----here we go!'); $SIG{'PIPE'}=sub { close FH; exit 0; }; while (1) { print multipart_start(-type=>'text/plain'). readprocuptime.multipart_end; sleep 1; }; -
Ici, un example de flux de données (5 secondes).
HTTP/1.0 200 OK Server: cmdline Date: Sat, 23 Aug 2008 10:29:25 GMT Content-Type: multipart/x-mixed-replace;boundary="----here we go!" WARNING: YOUR BROWSER DOESN'T SUPPORT THIS SERVER-PUSH TECHNOLOGY. ------here we go! Content-Type: text/plain 18583442.24 513590.71 ------here we go! Content-Type: text/plain 18583443.25 513590.80 ------here we go! Content-Type: text/plain 18583444.26 513591.81 ------here we go! Content-Type: text/plain 18583445.26 513592.82 ------here we go! -
Et voici la première version du ecmascript / javascript
que j'ai écrit pour faire le job.
<script type="text/ecmascript"> var uptm = 0; var idle = 0; var wasup = 1200903924000; var snapu = 0; var snapi = 0; var deviation = .014656302035730131832815841454; // deviation = 41.987deg * pi / 180 / (100/2) ; function rpltxt(fieldid,newtext) { var targettext = document.getElementById(fieldid); var os=targettext.lastChild; var ns=document.createTextNode(newtext); targettext.replaceChild(ns,os); } function fn(event) { var maarray = event.target.responseText.split(' '); var duptim = maarray[0] - uptm; var didle = maarray[1] - idle; uptm = maarray[0]; idle = maarray[1]; var dte= new Date( Math.ceil(uptm)*1000+wasup ); rpltxt('tspan931','System time: '+dte.toLocaleDateString()+ ', '+dte.toLocaleTimeString()); var prct = Math.abs(duptim-didle)/duptim*100; var aiguille=document.getElementById('aiguille'); var xpos = 231 + 270 * Math.sin( ( prct - 50 ) * deviation ); var ypos = 371 - 270 * Math.cos( ( prct - 50 ) * deviation ); aiguille.setAttribute('d','M 231 371L '+xpos+','+ypos); rpltxt('tspan923',prct.toFixed(2)+'%'); aiguille=document.getElementById('average'); if (snapu == 0) { aiguille.setAttribute('style','stroke:#ffaaff;stroke-opacity:.7;stroke-width:7;'); var avgtxt = document.getElementById('tspan925'); avgtxt.setAttribute('fill','#dd88dd'); var mprct = Math.abs(uptm - idle)/uptm*100; rpltxt('tspan925','Average: '+mprct.toFixed(2)+'%'); dte= new Date( wasup ); rpltxt('tspan929','Was up: '+dte.toLocaleDateString()+ ', '+dte.toLocaleTimeString()); } else { aiguille.setAttribute('style','stroke:#ffffaa;stroke-opacity:.7;stroke-width:7;'); var avgtxt = document.getElementById('tspan925'); avgtxt.setAttribute('fill','#dddd88'); var mprct = Math.abs((uptm-snapu) - (idle-snapi))/(uptm-snapu)*100; rpltxt('tspan925','SnapAvg: '+mprct.toFixed(2)+'%'); dte= new Date( Math.ceil(snapu)*1000+wasup ); rpltxt('tspan929','Snap: '+dte.toLocaleDateString()+ ', '+dte.toLocaleTimeString()); } xpos = 231 + 270 * Math.sin( ( mprct - 50 ) * deviation ); ypos = 371 - 270 * Math.cos( ( mprct - 50 ) * deviation ); aiguille.setAttribute('d','M 231 371L '+xpos+','+ypos); } function first(event) { var zrequest = new XMLHttpRequest(); zrequest.multipart = true; zrequest.open('GET','/cgi-bin/nph-cpu.txt',false); zrequest.onload = fn; zrequest.send(null); } function snap() { snapu=uptm; snapi=idle; } function desnap() { snapu=0; snapi=0; } window.onload = first; </script>