NGraph - Graphers

Le grapher, quant à lui, est chargé de générer les pages HTML et d'appeler rrdtool pour dessiner les graphes, depuis les RRD.  Il gère aussi le cache d'images, via rrdtool, mais aussi via un test sur la date de modification du plugin pour effacer le graphes qui auraient été générées avant une correction du code.

Avec les bases définies dans les tests, je tire les graphes suivants :

Génération de la page principale

Pour générer la page d'index, le grapher charge chaque plugin, instancie les objets objets qui implémentent Grapher, et passe en revue toutes les bases RRD présentes dans le répertoire.  L'objet graphe est interrogé sur sa propriété iterate, qui renvoie false si le graphe n'a pas besoin des sources de données pour se dessiner, et ne revoie alors qu'une seule page, ou true dans le cas contraire.  Des deux manières, c'est la méthode index(file) qui est appelée, et qui doit exécuter (yield) le bloc pour chaque page qu'il veut générer, avec pour paramètres une clé qui sera passée dans le lien, et le texte à afficheri (charge au plugin de présenter le nom d'hôte ou tout info nécessaire, qui doivent donc être décelés dans le nom de la RRD).

Il faut noter que, contrairement au tester, ici, une même donnée peut être exploitée par plusieurs plugins.  De la même manière, un plugin peut en fait faire des graphes sur plusieurs sources (cfr plus bas).

La page principale est composée d'un <ul> et d'une ligne par lien renvoyé.  Ils sont en ce moment classés par ordre alphabétique.

Génération des pages de graphes

Une page présente, via un plugin, des groupes de graphes, organisés par périodes.  Le titre de la page est celui qui est renvoyé dans l'index, puis le titre des périodes est tiré par RRA, pour finalement arriver au titre de chaque graphe, qui vient du plugin.

Une fois que l'utilisateur arrive sur une page, le grapher est relancé pour cette fois-ci interroger chaque plugin sur sa méthode register(link), avec, en paramètre, la clé renvoyée plus haut dans la composition de l'index.  Cette methode itère à son tour sur le nombre de graphes qu'elle doit afficher, donnant un identifiant a chaque graphe.

Par exemple, le grapheur de ping renverra une clé pour le graphe de la latence, et une pour le graphe des pertes.  Ensuite, un graphe sera fait par archive (les rras des testeurs) définie dans la base de données.  Cela signifie que le ping affichera un total de huit graphes (latence et pertes, sur un jour, un semaine, un mois et une année chacun).

L'étape suivante consiste à refaire appel à index, pour afficher le titre en haut de page, puis subtitle(id) avec l'identifiant, pour dessiner le titre à l'intérieur de chaque graphe.

Dessin du graphe proprement dit

Le graphe est composé de quatre parties, générées plus ou moins automatiquement.

Le titre, au dessus, est fait depuis la propriété subtitle(id), avec entre parenthèses la propriété title de la RRA.

Pour pouvoir composer le graphique, la fonction graph(link, id, gfx, file) est sollicitée.  Ses quatre paramètres sont respectivement la clé de la page, l'identifiant du graphe, un objet RRGGroup qui recevra toutes les méthodes, et le nom de la base de données principale.

La première partie de cette méthode consistera classiquement à ajouter des définitions de données à l'objet RRGGroup, via la méthode adddef(name, rrd, data, funct[, label][, fmt]), reçoit respectivement : un nom unique, utilisé pour la suite, le nom de la base de données où puiser les données (classiquement le paramètre file, mais peut très bien être autre chose), le nom de la série de données à utiliser (la clé utilisée par le tester pour l'insertion), la fonction d'aggrégation (sous forme de symbole, donc :AVERAGE, :MIN, :MAX), une étiquette et un format numérique, utilisés dans le tableau de la légende, qui peuvent être omis.  Cette fonction crée et renvoie des objets de type RRDef.

La méthode suivante, addcdef(name, expr[, label][, fmt]), travaille de la même manière, mais, au lieu de lire les données depuis les RRD, elle travaille sur des définitions faites plus haut avec une expression en notation polonaise inversée et instancie un objet de type RRCDef qu'elle renvoie.  Ce qu'on peut exactement réaliser avec dépasse un peu le cadre de cette documentation, mais les pages de manuel de rrdtool explicitent cela très bien.

Au final, la méthode addgraph(type, data[, color][, label][, stack]) permet de faire les courbes en elles-mêmes.  Ses paramètres sont un type (:LINE ou :AREA), la clé de donnée (def ou cdef) à afficher, et, optionnellement, une couleur, une étiquette, et un paramètre booléen qui permet d'additionner les valeurs.  Elle crée et renvoie un objet RRG.  Petit détail : les couleurs sont choisies par défaut depuis une liste de huit couleurs distinctes, qui ne sont utilisées qu'une fois par groupe de graphes (donc, même si la latence et les pertes sont dessinées sur deux graphes, l'une sera en bleu, et l'autre en rouge).  Les couleurs peuvent être spécifiées sous format hexadécimal ou sous format d'un des symboles suivants : :red, :blue, :green, :magenta, :cyan, :yellow, :lightgray, :darkgray.

Ces élements sont utilisés pour afficher les courbes, mais aussi un résumé numérique, et la légende.

Le résumé numérique se fait par le biais d'une série d'objets RRLegend, qui permet d'automatiser la récupération de données sur toutes les sources dessinées.  Par défaut, le résumé se fait avec une colonne maximum et une colonne moyenne.  Le nom de la donnée s'affiche entre les deux, avec des points pour aider à la lisibilité.  Il est prévu (ce n'est pas encore effectif) de pouvoir manipuler plus facilement les légendes, pour, par exemple, faire un affichage plus sous forme de tableau, et avoir d'autres aggrégations.

Les définitions de type RRDef et RRCDef peuvent toutes les deux donner lieu à des lignes dans le tableau, à condition de renseigner une étiquette et un format numérique.  Si un de ces deux paramètres sont absents, rien n'apparaîtra.  Il est parfois utile d'afficher la légende uniquement sur la valeur calculée (cas de la charge de la machine qui doit être divisée par 100 pour être affichée et dessinée), ou de dessiner une valeur et d'en renseigner une autre (par exemple, les graphes de bande passante inversent un des deux sens pour faire un graphique 'miroir', mais la légende ne doit pas comprendre le nombre négatif).

Finalement, si l'objet RRG renseigne une étiquette, celle-ci est utilisée pour faire la légende en bas, avec la pastille de la couleur adéquate.

Quelques fonctions sont disponibles pour aider à l'écriture d'expressions de calcul : rpn_ifu(value, uvalue) (ajoute une condition pour renvoyer uvalue si value est indéfinie), rpn_zu(value) (permet de revoyer zéro si value est indéfinie), rpn_sum(*values) (renvoie l'expression qui somme n'importe quel nombre d'arguments), rpn_avg(*values) (idem avec une moyenne).

Il y a encore une série de propriétés de l'objet RRGroup qui sont plus ou moins directement liées aux paramètres de rrdtool graph : lowerbound et upperbound qui définissent les bornes théoriques du graphe, strict qui oblige le programme à respecter ces bornes, percent qui, quand elle est mise à true, est un raccourci pour forcer un affichage strict et des bornes de 0 à 100, logarithmic spécifie une échelle logarithmique, et base qui permet de donner le nombre d'unités par 'kilo' (au lieu des 1000 par défaut).

Il faut aussi noter que le système automatise totalement la répétition des graphes pour chaque période de temps.

Retour - Me contacter : merci de lire ceci d'abord.

Page modifiée en dernier le 30/10/2006 - XHTML 1.1 strict et CSS 2.0.