{"id":698,"date":"2020-08-26T12:49:29","date_gmt":"2020-08-26T10:49:29","guid":{"rendered":"http:\/\/blog.nosland.com\/?p=698"},"modified":"2020-08-26T12:49:31","modified_gmt":"2020-08-26T10:49:31","slug":"grafana","status":"publish","type":"post","link":"http:\/\/blog.nosland.com\/?p=698","title":{"rendered":"GRAFANA"},"content":{"rendered":"\n<p>Tout d\u2019abord, l\u2019interface de Grafana seule ne sert \u00e0 rien. Pour fonctionner elle a besoin d\u2019\u00eatre aliment\u00e9 par des \u00ab&nbsp;Datas Sources&nbsp;\u00bb. La data source primaire que j\u2019ai utilis\u00e9 est Graphite qui lui concentre les donn\u00e9es dans une base \u00ab&nbsp;whisper&nbsp;\u00bb qui ressemble \u00e0 du rrd via carbon-cache. Sur les serveurs cibles, afin d\u2019alimenter graphite, j\u2019utilise collectd qui est un deamon qui collecte des donn\u00e9es et les envoie \u00e0 un serveur collectd sur le mode client\/serveur. Ainsi il convient donc d\u2019installer sur le serveur le moteur collectd qui va travailler avec carbon-cache.<\/p>\n\n\n\n<p>Pour r\u00e9sumer sur le serveur&nbsp;:<\/p>\n\n\n\n<ul><li>Collectd\u00a0: il r\u00e9alise la collecte des donn\u00e9es sur les diff\u00e9rents serveurs<\/li><li>Graphite\u00a0: Il concentre les donn\u00e9es dans une base via carbon-cache et pr\u00e9sente une API Rest \u00e0 Grafana afin d\u2019utiliser les donn\u00e9es en base.<\/li><li>Grafana\u00a0: Il utilise l\u2019API de graphite afin de mettre en forme diff\u00e9rents graphique.<\/li><\/ul>\n\n\n\n<h2>Collectd<\/h2>\n\n\n\n<p>Collectd permet de collecter des donn\u00e9es de multiples sources et de les agr\u00e9ger sous plusieurs types de stockage. A l\u2019UFC, il s&rsquo;agira de ces bons vieux fichiers rrd. Collectd est un logiciel tr\u00e8s l\u00e9ger auquel on ajoute un syst\u00e8me de plugin qui permet de collecter certains types de donn\u00e9es. Par exemple le plugin load permet de collecter le load average sur un serveur. Ici je vais d\u00e9tailler l\u2019installation, la configuration de l\u2019architecture de type client\/serveur dans laquelle un serveur va collecter les donn\u00e9es de tous les clients.<\/p>\n\n\n\n<p>Serveur \u00e0 172.20.16.63 graphite.nosland.com<\/p>\n\n\n\n<p>Client \u00e0 172.20.16.65 moodle.nosland.com<\/p>\n\n\n\n<p><strong>Installation et configuration du serveur<\/strong><\/p>\n\n\n\n<p class=\"has-white-color has-black-background-color has-text-color has-background\">Graphite$> apt-get install collectd collectd-utils<\/p>\n\n\n\n<p>Il faut ensuite \u00e9diter le fichier de configuration principal\u00a0: \/etc\/collectd\/collectd.conf<\/p>\n\n\n\n<p class=\"has-white-color has-black-background-color has-text-color has-background\">Hostname \u00ab\u00a0graphite.nosland.com\u00a0\u00bb<br>FQDNLookup true<br>TypesDB \u00ab\u00a0\/usr\/share\/collectd\/types.db\u00a0\u00bb \u00ab\u00a0\/etc\/collectd\/my_types.db\u00a0\u00bb<\/p>\n\n\n\n<p>Une fois ces quelques param\u00e8tres v\u00e9rifier, on relance le daemon systemctl restart collectd<\/p>\n\n\n\n<p>Si tout est OK, on devrait avoir des fichiers dans le dossier \/var\/lib\/collectd\/rrd\/graphite.serveurs.dsi.univ-fcomte.fr\/<\/p>\n\n\n\n<p>\u00a0Il faut maintenant configurer le serveur d\u2019\u00e9coute, on \u00e9dite de nouveau le fichier \/etc\/collectd\/collectd.conf<\/p>\n\n\n\n<p>Il faut s\u2019assurer que la ligne de d\u00e9claration du plugin \u00ab\u00a0network\u00a0\u00bb n\u2019est pas comment\u00e9. Si c\u2019est le cas, il faut la d\u00e9-commenter\u00a0:<\/p>\n\n\n\n<p class=\"has-white-color has-black-background-color has-text-color has-background\">#LoadPlugin mysql<br>#LoadPlugin netlink<br>LoadPlugin network\u00a0 <strong>&lt;= d\u00e9commenter cette ligne\u00a0!<\/strong><br>#LoadPlugin nfs<br>#LoadPlugin nginx<\/p>\n\n\n\n<p>Puis nous allons configurer le serveur d\u2019\u00e9coute. Il faut pour cela se rendre dans la partie de configuration des plugins et rep\u00e9rer la partie concernant le plugin \u00ab\u00a0network\u00a0\u00bb<\/p>\n\n\n\n<p>Notre serveur va \u00e9couter sur son interface r\u00e9seau eth0 (172.20.16.63) et sur le port 25826 (udp). Pensez \u00e0 ouvrir le FW.<\/p>\n\n\n\n<p>On rep\u00e8re le d\u00e9but de la configuration du plugin par la balise\u00a0: \u00ab\u00a0&lt;Plugin network>\u00a0\u00bb<\/p>\n\n\n\n<p>Dans le tableau suivant, je vous donne la configuration d\u2019origine dans la colonne de gauche et la configuration que l\u2019on doit obtenir dans la colonne de droite. En gras les lignes qui ont \u00e9t\u00e9 d\u00e9-comment\u00e9es et\/ou modifi\u00e9es.<\/p>\n\n\n\n<figure class=\"wp-block-table\"><table><tbody><tr><td>#&lt;Plugin network><br>#\u00a0\u00a0\u00a0 \u00a0\u00a0\u00a0# client setup:<br>#\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 Server \u00ab\u00a0ff18::efc0:4a42\u00a0\u00bb \u00ab\u00a025826\u00a0\u00bb<br>#\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 &lt;Server \u00ab\u00a0239.192.74.66\u00a0\u00bb \u00ab\u00a025826\u00a0\u00bb><br>#\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 SecurityLevel Encrypt<br>#\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 Username \u00ab\u00a0user\u00a0\u00bb<br>#\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 Password \u00ab\u00a0secret\u00a0\u00bb<br>#\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 Interface \u00ab\u00a0eth0\u00a0\u00bb<br>#\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 ResolveInterval 14400<br>#\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 &lt;\/Server><br>#\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 TimeToLive 128<br>#<br>#\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 # server setup:<br>#\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 Listen \u00ab\u00a0ff18::efc0:4a42\u00a0\u00bb \u00ab\u00a025826\u00a0\u00bb<br>#\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 &lt;Listen \u00ab\u00a0172.20.16.63\u00a0\u00bb \u00ab\u00a025826\u00a0\u00bb><br>#\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 SecurityLevel Sign<br>#\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 AuthFile \u00ab\u00a0\/etc\/collectd\/passwd\u00a0\u00bb<br>#\u00a0 \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0Interface \u00ab\u00a0eth0\u00a0\u00bb<br>#\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 &lt;\/Listen><br>#\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 MaxPacketSize 1452<br>#<br>#\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 # proxy setup (client and server as above):<br>#\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 Forward true<br>#<br>#\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 # statistics about the network plugin itself<br>#\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 ReportStats false<br>#<br>#\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 # \u00ab\u00a0garbage collection\u00a0\u00bb<br>#\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 CacheFlush 1800<br># &lt;\/Plugin><\/td><td>-><\/td><td><br><br><br><br><strong>&lt;Plugin network><\/strong><br>#\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 # client setup:<br>#\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 Server \u00ab\u00a0ff18::efc0:4a42\u00a0\u00bb \u00ab\u00a025826\u00a0\u00bb<br>#\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 &lt;Server \u00ab\u00a0239.192.74.66\u00a0\u00bb \u00ab\u00a025826\u00a0\u00bb><br>#\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 SecurityLevel Encrypt<br>#\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 Username \u00ab\u00a0user\u00a0\u00bb<br>#\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 Password \u00ab\u00a0secret\u00a0\u00bb<br>#\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 Interface \u00ab\u00a0eth0\u00a0\u00bb<br>#\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 ResolveInterval 14400<br>#\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 &lt;\/Server><br>#\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 TimeToLive 128<br>#<br>#\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 # server setup:<br>#\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 Listen \u00ab\u00a0ff18::efc0:4a42\u00a0\u00bb \u00ab\u00a025826\u00a0\u00bb<br><strong>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 &lt;Listen \u00ab\u00a0172.20.16.63\u00a0\u00bb \u00ab\u00a025826\u00a0\u00bb><\/strong><br>#\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 SecurityLevel Sign<br>#\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 AuthFile \u00ab\u00a0\/etc\/collectd\/passwd\u00a0\u00bb<br>#\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 Interface \u00ab\u00a0eth0\u00a0\u00bb<br><strong>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 &lt;\/Listen><\/strong><br>#\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 MaxPacketSize 1452<br>#<br>#\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 # proxy setup (client and server as above):<br>#\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 Forward true<br>#<br>#\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 # statistics about the network plugin itself<br>#\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 ReportStats false<br>#<br>#\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 # \u00ab\u00a0garbage collection\u00a0\u00bb<br>#\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 CacheFlush 1800<br><strong>&lt;\/Plugin><\/strong><\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p>On pourrait ajouter une authentification mais vu que notre environnement est exclusivement sur un r\u00e9seau priv\u00e9 et contr\u00f4l\u00e9, je me suis pass\u00e9 de cette configuration.<br>Il suffit maintenant de relancer le service\u00a0: systemctl restart collectd<\/p>\n\n\n\n<p class=\"has-black-color has-white-background-color has-text-color has-background\">Si tout est ok on doit voir notre processus qui tourne\u00a0:<\/p>\n\n\n\n<p class=\"has-white-color has-black-background-color has-text-color has-background\"><br>Graphite$> netstat -ntulape | grep 25826 udp\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 0\u00a0\u00a0\u00a0\u00a0\u00a0 0 172.20.16.63:25826\u00a0\u00a0\u00a0\u00a0\u00a0 0.0.0.0:*\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 18943\u00a0\u00a0\u00a0\u00a0\u00a0 595\/collectd<\/p>\n\n\n\n<p><strong>Installation et configuration de collectd sur le client<\/strong><\/p>\n\n\n\n<p>Comme pour le serveur on commence par installer les paquets collectd et collectd-utils<\/p>\n\n\n\n<p class=\"has-white-color has-black-background-color has-text-color has-background\">Moodle2019$> apt-get install collectd collectd-utils<\/p>\n\n\n\n<p>Ensuite on modifie la valeur du hostname : <\/p>\n\n\n\n<p class=\"has-white-color has-black-background-color has-text-color has-background\">Hostname \u00ab\u00a0moodle.nosland.com\u00a0\u00bb<\/p>\n\n\n\n<p>On d\u00e9-commente les plugins qui nous int\u00e9ressent\u00a0: cpu, df, disk, entropy, etc\u2026<br>On s\u2019assure que le plugin \u00ab\u00a0network\u00a0\u00bb ne soit pas comment\u00e9\u00a0:<\/p>\n\n\n\n<p class=\"has-white-color has-black-background-color has-text-color has-background\">#LoadPlugin netlink<br>LoadPlugin network\u00a0 <strong>&lt;= d\u00e9commenter cette ligne\u00a0!<\/strong><\/p>\n\n\n\n<p>Puis on configure le plugin network afin qu\u2019il envoie sa collecte sur notre serveur\u00a0:<\/p>\n\n\n\n<p class=\"has-white-color has-black-background-color has-text-color has-background\">&lt;Plugin network><br>&lt;Server \u00ab\u00a0172.20.16.63\u00a0\u00bb \u00ab\u00a025826\u00a0\u00bb><br>&lt;\/Server><br>&lt;\/Plugin><\/p>\n\n\n\n<p>\u00a0\u00a0\u00a0\u00a0\u00a0<em>\u00a0\u00a0 (j\u2019ai retir\u00e9 toutes les lignes que je laisse en commentaire dans la configuration du plugin).<\/em><\/p>\n\n\n\n<p>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 On relance le service\u00a0: systemctm restart collectd<br>Normalement on devrait avoir un dossier avec le nom du client sur le serveur\u00a0:<\/p>\n\n\n\n<p class=\"has-white-color has-black-background-color has-text-color has-background\">Graphite$> ls \/var\/lib\/collectd\/rrd\/<br>graphite.nosland.com\u00a0\u00a0\u00a0 \u00a0Moodle.nosland.com<\/p>\n\n\n\n<p><strong>Graphite<\/strong><\/p>\n\n\n\n<p>Graphite se d\u00e9compose en 3 parties distinctes&nbsp;:<\/p>\n\n\n\n<ul><li>Whisper qui est une base de donn\u00e9es (proche de rrd)<\/li><li>Carbon qui un deamon qui permet d\u2019agr\u00e9ger les donn\u00e9es dans Whisper.<\/li><li>Graphite-web qui est un webservice qui pr\u00e9sente une API REST \u00e0 grafana. (c\u2019est une webapp qui tourne en Python en s\u2019appuyant sur django.)<\/li><\/ul>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" width=\"542\" height=\"398\" src=\"http:\/\/blog.nosland.com\/wp-content\/uploads\/2020\/08\/image.png\" alt=\"\" class=\"wp-image-701\" srcset=\"http:\/\/blog.nosland.com\/wp-content\/uploads\/2020\/08\/image.png 542w, http:\/\/blog.nosland.com\/wp-content\/uploads\/2020\/08\/image-300x220.png 300w\" sizes=\"(max-width: 542px) 100vw, 542px\" \/><\/figure>\n\n\n\n<p>On peut utiliser Graphite de deux fa\u00e7ons dans notre infra&nbsp;:<\/p>\n\n\n\n<ul><li>Soit on utilise les donn\u00e9es whisper avec le deamon Carbon<\/li><li>Soit on fait lire directement nos fichiers \u00e0 graphite-web<\/li><\/ul>\n\n\n\n<p><strong>Installation de Graphite-web<\/strong><\/p>\n\n\n\n<p>On a besoin d\u2019installer le package PIP car graphite-web n\u2019est plus maintenu par Debian\u00a0:<\/p>\n\n\n\n<p class=\"has-white-color has-black-background-color has-text-color has-background\">Graphite$> apt-get install python-pip<\/p>\n\n\n\n<p>Graphite-web utilise django en tant que d\u00e9pendance, on l\u2019installe donc<\/p>\n\n\n\n<p class=\"has-white-color has-black-background-color has-text-color has-background\">Graphite$> pip install django<\/p>\n\n\n\n<p>Puis on installe les autres d\u00e9pendances\u00a0:<\/p>\n\n\n\n<p class=\"has-white-color has-black-background-color has-text-color has-background\">Graphite$> apt-get install python-dev libcairo2-dev libffi-dev build-essential apache2 libapache2-mod-wsgi python-rrdtool<\/p>\n\n\n\n<p>On fait ensuite un lien symbolique sur un dossier \/opt\/graphite. Ceci permettra de faire des mises \u00e0 jours facilement par la suite\u00a0:<\/p>\n\n\n\n<p class=\"has-white-color has-black-background-color has-text-color has-background\">Graphite$> ln \u2013s \/opt\/graphite-1.1.5\/ \/opt\/graphite<\/p>\n\n\n\n<p>Ensuite on initialise la BDD (sqlite)\u00a0:<\/p>\n\n\n\n<p class=\"has-white-color has-black-background-color has-text-color has-background\">Graphite$> PYTHONPATH=\/opt\/graphite\/webapp django-admin.py migrate &#8211;settings=graphite.settings &#8211;run-syncdb<\/p>\n\n\n\n<p>\u00c7a cr\u00e9\u00e9 un fichier \/opt\/graphite\/storage\/graphite.db<br>Nous allons ensuite r\u00e9cup\u00e9rer un exemple pour la configuration afin de gagner du temps et de ne modifier que ce dont nous avons besoin\u00a0:<\/p>\n\n\n\n<p class=\"has-white-color has-black-background-color has-text-color has-background\">Graphite$> mv \/opt\/graphite\/webapp\/graphite\/local_settings.py.example \/opt\/graphite\/webapp\/graphite\/local_settings.py<\/p>\n\n\n\n<p>Il y a deux param\u00e8tres \u00e0 modifier\u00a0:<\/p>\n\n\n\n<p class=\"has-white-color has-black-background-color has-text-color has-background\">SECRET_KEY\u00a0= &lsquo;DSI-UnivFcomte&rsquo; (c\u2019est une clef de hashage)<br>TIME_ZONE = &lsquo;Europe\/Paris&rsquo; \u00a0(Besan\u00e7on n\u2019\u00e9tant pas disponible^^)<\/p>\n\n\n\n<p>On a besoin maintenant d\u2019installer le module apache wsgi configur\u00e9 pour Graphite\u00a0:<\/p>\n\n\n\n<p class=\"has-white-color has-black-background-color has-text-color has-background\">Graphite$> mv \/opt\/graphite\/conf\/graphite.wsgi.example \/opt\/graphite\/conf\/graphite.wsgi<\/p>\n\n\n\n<p>Il faut ensuite g\u00e9n\u00e9rer les fichiers statics de l\u2019apply web (css, js, images, etc\u2026) dans le dossier \/opt\/graphite\/static<\/p>\n\n\n\n<p class=\"has-white-color has-black-background-color has-text-color has-background\">Graphite$> PYTHONPATH=\/opt\/graphite\/webapp django-admin.py collectstatic &#8211;noinput &#8211;settings=graphite.settings<\/p>\n\n\n\n<p>Enfin nous devons changer le propri\u00e9taire du dossier \/opt\/graphite\/storage qui doit \u00eatre utilisable par apache (www-data).<\/p>\n\n\n\n<p class=\"has-white-color has-black-background-color has-text-color has-background\">Graphite$> chown -R www-data: \/opt\/graphite\/storage\/<\/p>\n\n\n\n<p>Il faut ensuite cr\u00e9er le fichier de configuration apache pour graphite-web. Vu que Grafana est sur le m\u00eame serveur, graphite-web ne va \u00e9couter que sur le loopback (127.0.01), et sur le le port 5566 (port par d\u00e9faut d\u00e9finit dans la webapp de graphite).<br>On cr\u00e9\u00e9 donc \/etc\/apache2\/sites-available\/graphite-web.conf<\/p>\n\n\n\n<p class=\"has-white-color has-black-background-color has-text-color has-background\">WSGISocketPrefix \/run\/wsgi<br>Listen 5566<br>&lt;VirtualHost 127.0.0.1:5566><br>DocumentRoot \u00ab\u00a0\/opt\/graphite\/webapp\u00a0\u00bb<br>ErrorLog \/var\/log\/apache2\/graphite-web_error.log<br>CustomLog \/var\/log\/apache2\/graphite-web_access.log common<br># Configuration de WSGI<br>WSGIDaemonProcess graphite processes=5 threads=5 display-name=&rsquo;%{GROUP}&rsquo; inactivity-timeout=120<br>WSGIProcessGroup graphite<br>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 WSGIApplicationGroup %{GLOBAL}<br>WSGIImportScript \/opt\/graphite\/conf\/graphite.wsgi process-group=graphite application-group=%{GLOBAL}<br>WSGIScriptAlias \/ \/opt\/graphite\/conf\/graphite.wsgi<br># Pour rendre le fichier graphite.wsgi visible par apache<br>&lt;Directory \/opt\/graphite\/conf\/><br>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 Require all granted<br>&lt;\/Directory><br>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 # Alias pour les fichiers statiques<br>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 Alias \/static\/ \/opt\/graphite\/static\/<br># Autorisation sur les fichiers statiques<br>&lt;Directory \/opt\/graphite\/static><br>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 Require all granted<br>&lt;\/Directory><br># L&rsquo;alias vers le dossier media de django<br>Alias \/media\/ \u00ab\u00a0\/usr\/local\/lib\/python2.7\/dist-packages\/django\/contrib\/admin\/media\/\u00a0\u00bb<br>&lt;\/VirtualHost><\/p>\n\n\n\n<p>On active le fichier de conf, puis on teste la config, et enfin si tout est OK on relance le service apache2\u00a0:<\/p>\n\n\n\n<p class=\"has-white-color has-black-background-color has-text-color has-background\">Graphite$> a2ensite graphite-web.conf<br>Graphite$> a2enmod wsgi<br>Graphite$> apachectl -t<br>Graphite$> systemctl restart apache2<\/p>\n\n\n\n<p>Maintenant, nous avons notre graphite qui tourne et qui cherche des fichiers pour alimenter sa base et les livrer en API, mais dans le fichier de configuration de graphite\u00a0: local_settings.py la variable RRD_DIR est positionn\u00e9e sur \/opt\/graphite\/storage\/rrd\/ or collectd conserve les fichiers dans le dossier \/var\/lib\/collectd\/rrd<\/p>\n\n\n\n<p>Autre d\u00e9tails, nous avons vu que collectd cr\u00e9\u00e9 des dossiers par serveur avec la variable qui a \u00e9t\u00e9 d\u00e9finit dans le fichier de conf du client (HOSTNAME). Or nous utilisons des FQDN, et le probl\u00e8me est que graphite ne sait pas interpr\u00e9ter les \u2018points\u2019 donc nous allons cr\u00e9er un lien symbolique pour chaque serveur mais en prenant soin de remplacer les \u00ab\u00a0.\u00a0\u00bb par des \u00ab\u00a0_\u00a0\u00bb\u00a0:<\/p>\n\n\n\n<p class=\"has-white-color has-black-background-color has-text-color has-background\">Graphite$> ln -s \/var\/lib\/collectd\/rrd\/graphite.nosland.com\/ \/opt\/graphite\/storage\/rrd\/ graphite_nosland_com<br>Graphite$> ln -s \/var\/lib\/collectd\/rrd\/moodle.nosland.com\/ \/opt\/graphite\/storage\/rrd\/ moodle_nosland_com<\/p>\n\n\n\n<p><strong>Installation de Carbon<\/strong><\/p>\n\n\n\n<p>Carbon va nous \u00eatre utile pour pr\u00e9fixer les donn\u00e9es de collectd de fa\u00e7on ensuite \u00e0 pouvoir adapter la r\u00e9tention comme on le souhaite.<br>Pour installer on utilise apt\u00a0:<\/p>\n\n\n\n<p class=\"has-white-color has-black-background-color has-text-color has-background\">Graphite$> apt-get install graphite-carbon<\/p>\n\n\n\n<p>Pour s\u00e9curiser un minimum on fait \u00e9couter le deamon sur le loopback (127.0.0.1). On modifie donc le fichier \/etc\/carbon\/carbon.conf\u00a0:<\/p>\n\n\n\n<p class=\"has-white-color has-black-background-color has-text-color has-background\">LINE_RECEIVER_INTERFACE = 127.0.0.1<\/p>\n\n\n\n<p>On relance ensuite le service<\/p>\n\n\n\n<p class=\"has-white-color has-black-background-color has-text-color has-background\">Graphite$> systemctl restart carbon-cache.service<\/p>\n\n\n\n<p>On active ensuite le plugin write_graphite de collectd. En fait le daemon collectd va envoyer ses donn\u00e9es \u00e0 Carbon (qui \u00e9coute sur le port 2003 par d\u00e9faut), et va les pr\u00e9fixer de \u00ab\u00a0collectd_\u00a0\u00bb<br>On \u00e9dite le fichier \/etc\/collectd\/collectd.conf et on ajoute \u00e0 la fin de celui-ci\u00a0:<\/p>\n\n\n\n<p class=\"has-white-color has-black-background-color has-text-color has-background\">LoadPlugin write_graphite<br>&lt;Plugin write_graphite><br>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 &lt;Node \u00ab\u00a0localhost\u00a0\u00bb><br>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 Port \u00ab\u00a02003\u00a0\u00bb<br>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0protocol \u00ab\u00a0tcp\u00a0\u00bb<br>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 ReconnectInterval 0<br>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 LogSendErrors true<br>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 Prefix \u00ab\u00a0collectd_\u00a0\u00bb<br>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 StoreRates true<br>&lt;\/Node><br>&lt;\/Plugin><\/p>\n\n\n\n<p>Et on relance collectd\u00a0: systemctl restart collectd.service<\/p>\n\n\n\n<p>Nous allons maintenant configurer la r\u00e9tention dans la base whisper via le fichier \/etc\/carbon\/storage-schemas.conf. Vu que nos fichiers sont pr\u00e9fix\u00e9s nous allons utiliser une regexp pour d\u00e9finir la r\u00e9tention.<\/p>\n\n\n\n<p>On \u00e9dite donc le fichier storage-schemas.conf<\/p>\n\n\n\n<p class=\"has-white-color has-black-background-color has-text-color has-background\">[collectd]<br>pattern = ^collectd.*<br>retentions = 10s:1h,1m:1d,10m:1y<\/p>\n\n\n\n<p>Ces 3 dur\u00e9es de r\u00e9tention vont r\u00e9partir les donn\u00e9es dans 3 diff\u00e9rents groupes\u00a0:<br><\/p>\n\n\n\n<ul><li>Une pr\u00e9cision de 10 secondes sur une heure<\/li><li>Une pr\u00e9cision de 1 minutes sur 1 jour<\/li><li>Une pr\u00e9cision de 10 minutes pour une ann\u00e9e<\/li><\/ul>\n\n\n\n<p>On relance carbon\u00a0: systemctl restart carbon-cache<\/p>\n\n\n\n<p><strong>Installation de Grafana<\/strong><\/p>\n\n\n\n<p>Il faut commencer par ajouter le d\u00e9p\u00f4t officiel\u00a0:<\/p>\n\n\n\n<p>Graphite$> wget -q -O &#8211; https:\/\/packages.grafana.com\/gpg.key | sudo apt-key add &#8211;<br>Graphite$> add-apt-repository \u00ab\u00a0deb https:\/\/packages.grafana.com\/oss\/deb stable main\u00a0\u00bb<br>Graphite$> apt-cache policy grafana<br>Graphite$>apt-get update &amp;&amp; apt-get install grafana \u2013y<br>Graphite$>systemctl daemon-reload<br><\/p>\n\n\n\n<p class=\"has-white-color has-black-background-color has-text-color has-background\">Graphite$> wget -q -O &#8211; https:\/\/packages.grafana.com\/gpg.key | sudo apt-key add &#8211;<br>Graphite$> add-apt-repository \u00ab\u00a0deb https:\/\/packages.grafana.com\/oss\/deb stable main\u00a0\u00bb<br>Graphite$> apt-cache policy grafana<br>Graphite$>apt-get update &amp;&amp; apt-get install grafana \u2013y<br>Graphite$>systemctl daemon-reload<br>Graphite$>systemctl enable grafana-server.service<br>Graphite$>systemctl start grafana-server.service<\/p>\n\n\n\n<p>Par d\u00e9faut grafana \u00e9coute sur toutes les interfaces sur le port 3000.<\/p>\n\n\n\n<p>On va modifier \u00e7a, et faire \u00e9couter grafana que sur le loopback. On ajoutera ensuite un vhost apache pour l\u2019acc\u00e8s.<\/p>\n\n\n\n<p>On modifie donc le fichier \/etc\/grafana\/grafana.ini<\/p>\n\n\n\n<p class=\"has-white-color has-black-background-color has-text-color has-background\">http_addr = 127.0.0.1<\/p>\n\n\n\n<p>Ensuite on relance le service&nbsp;: systemctl restart grafana-server<\/p>\n\n\n\n<p>On ajoute donc un vhost apache\u00a0\/etc\/apache2\/sites-available\/graphite.conf<\/p>\n\n\n\n<p class=\"has-white-color has-black-background-color has-text-color has-background\">&lt;VirtualHost *:443><br>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 ServerName graphite.nosland.com<br>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 Serveralias grafana.nosland.com<br>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 Header set X-Robots-Tag \u00ab\u00a0noindex, nofollow\u00a0\u00bb<br>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 ProxyRequests off<br>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 ProxyPass \/ http:\/\/127.0.0.1:3000\/<br>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 ProxyPassReverse \/ http:\/\/127.0.0.1:3000\/<br>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 SSLEngine on<br>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 SSLCertificateFile \/etc\/apache2\/ssl\/apache.pem<br>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 ErrorLog \/var\/log\/apache2\/graphite_error.log<br>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 CustomLog \/var\/log\/apache2\/graphite_access.log combined<br>&lt;\/VirtualHost><\/p>\n\n\n\n<p>Il ne reste plus qu\u2019\u00e0 activer le fichier de conf et relancer le service\u00a0:<\/p>\n\n\n\n<p class=\"has-white-color has-black-background-color has-text-color has-background\">Graphite$>a2ensite graphite.conf<br>Graphite$>a2enmod headers<br>Graphite$>a2enmod proxy<br>Graphite$>a2enmod proxy_http<br>Graphite$>apachectl -t<br>Graphite$>systemctl restart apache2.service<\/p>\n\n\n\n<p>On se connecte ensuite sur le site\u00a0: <\/p>\n\n\n\n<p><a href=\"https:\/\/graphite.serveurs.dsi.univ-fcomte.fr\">https:\/\/graphite.nosland.com<\/a><\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" width=\"605\" height=\"291\" src=\"http:\/\/blog.nosland.com\/wp-content\/uploads\/2020\/08\/image-1.png\" alt=\"\" class=\"wp-image-702\" srcset=\"http:\/\/blog.nosland.com\/wp-content\/uploads\/2020\/08\/image-1.png 605w, http:\/\/blog.nosland.com\/wp-content\/uploads\/2020\/08\/image-1-300x144.png 300w\" sizes=\"(max-width: 605px) 100vw, 605px\" \/><\/figure>\n\n\n\n<p>Par d\u00e9faut le login est admin et le mot de passe est password. On le modifie puis on peut commencer \u00e0 configurer notre grafana.<\/p>\n\n\n\n<p>On ajoute notre datasource (graphite-web)\u00a0:<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" width=\"197\" height=\"227\" src=\"http:\/\/blog.nosland.com\/wp-content\/uploads\/2020\/08\/image-2.png\" alt=\"\" class=\"wp-image-703\"\/><\/figure>\n\n\n\n<p>Puis on configure notre datasource comme sur la capture\u00a0:<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" width=\"605\" height=\"792\" src=\"http:\/\/blog.nosland.com\/wp-content\/uploads\/2020\/08\/image-3.png\" alt=\"\" class=\"wp-image-704\" srcset=\"http:\/\/blog.nosland.com\/wp-content\/uploads\/2020\/08\/image-3.png 605w, http:\/\/blog.nosland.com\/wp-content\/uploads\/2020\/08\/image-3-229x300.png 229w\" sizes=\"(max-width: 605px) 100vw, 605px\" \/><\/figure>\n\n\n\n<p>De l\u00e0 on peut commencer \u00e0 cr\u00e9er nos propres Dashboard\u00a0:<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" width=\"605\" height=\"319\" src=\"http:\/\/blog.nosland.com\/wp-content\/uploads\/2020\/08\/image-4.png\" alt=\"\" class=\"wp-image-705\" srcset=\"http:\/\/blog.nosland.com\/wp-content\/uploads\/2020\/08\/image-4.png 605w, http:\/\/blog.nosland.com\/wp-content\/uploads\/2020\/08\/image-4-300x158.png 300w\" sizes=\"(max-width: 605px) 100vw, 605px\" \/><\/figure>\n\n\n\n<p>On clique sur \u00ab\u00a0Add Query\u00a0\u00bb\u00a0:<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" width=\"604\" height=\"237\" src=\"http:\/\/blog.nosland.com\/wp-content\/uploads\/2020\/08\/image-5.png\" alt=\"\" class=\"wp-image-706\" srcset=\"http:\/\/blog.nosland.com\/wp-content\/uploads\/2020\/08\/image-5.png 604w, http:\/\/blog.nosland.com\/wp-content\/uploads\/2020\/08\/image-5-300x118.png 300w\" sizes=\"(max-width: 604px) 100vw, 604px\" \/><\/figure>\n\n\n\n<p>Dans \u00ab&nbsp;select m\u00e9tric&nbsp;\u00bb on va choisir Moodle2019 (sur les capture appel\u00e9e MoodleProd)<\/p>\n\n\n\n<p>Puis La m\u00e9moire, et ensuite le composant collectd r\u00e9cup\u00e9r\u00e9 pour la m\u00e9moire, ici le pourcentage de libre et enfin la valeur.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" width=\"447\" height=\"86\" src=\"http:\/\/blog.nosland.com\/wp-content\/uploads\/2020\/08\/image-6.png\" alt=\"\" class=\"wp-image-707\" srcset=\"http:\/\/blog.nosland.com\/wp-content\/uploads\/2020\/08\/image-6.png 447w, http:\/\/blog.nosland.com\/wp-content\/uploads\/2020\/08\/image-6-300x58.png 300w\" sizes=\"(max-width: 447px) 100vw, 447px\" \/><\/figure>\n\n\n\n<p>Imm\u00e9diatement Grafana nous dessine une courbe\u00a0:<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" width=\"605\" height=\"90\" src=\"http:\/\/blog.nosland.com\/wp-content\/uploads\/2020\/08\/image-7.png\" alt=\"\" class=\"wp-image-708\" srcset=\"http:\/\/blog.nosland.com\/wp-content\/uploads\/2020\/08\/image-7.png 605w, http:\/\/blog.nosland.com\/wp-content\/uploads\/2020\/08\/image-7-300x45.png 300w\" sizes=\"(max-width: 605px) 100vw, 605px\" \/><\/figure>\n\n\n\n<p>On peut modifier la couleur en cliquant sur le rectangle vert devant le nom de la m\u00e9tric\u00a0:<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" width=\"63\" height=\"37\" src=\"http:\/\/blog.nosland.com\/wp-content\/uploads\/2020\/08\/image-8.png\" alt=\"\" class=\"wp-image-709\"\/><\/figure>\n\n\n\n<p>Pour continuer, on clique sur le logo<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" width=\"76\" height=\"68\" src=\"http:\/\/blog.nosland.com\/wp-content\/uploads\/2020\/08\/image-9.png\" alt=\"\" class=\"wp-image-710\"\/><\/figure>\n\n\n\n<p>Sur cette partie on peut choisir le type de visualisation\u00a0:<\/p>\n\n\n\n<p>Le graph actuel, la valeur simple, un cadran, des barres, etc\u2026<\/p>\n\n\n\n<p>On va rester sur le graph dans cet exemple mais je ne vais pas tout d\u00e9tailler, le mieux et d\u2019essayer par vous-m\u00eame.<\/p>\n\n\n\n<p>Pour finaliser mon graphique, je vais lui passer l\u2019unit\u00e9 adapt\u00e9e\u00a0:<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" width=\"605\" height=\"276\" src=\"http:\/\/blog.nosland.com\/wp-content\/uploads\/2020\/08\/image-10.png\" alt=\"\" class=\"wp-image-711\" srcset=\"http:\/\/blog.nosland.com\/wp-content\/uploads\/2020\/08\/image-10.png 605w, http:\/\/blog.nosland.com\/wp-content\/uploads\/2020\/08\/image-10-300x137.png 300w\" sizes=\"(max-width: 605px) 100vw, 605px\" \/><\/figure>\n\n\n\n<p>Et je finis avec un peu de pr\u00e9sentation et de valeurs clefs\u00a0: mini, maxi, moyen et actuelle\u00a0:<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" width=\"605\" height=\"140\" src=\"http:\/\/blog.nosland.com\/wp-content\/uploads\/2020\/08\/image-11.png\" alt=\"\" class=\"wp-image-712\" srcset=\"http:\/\/blog.nosland.com\/wp-content\/uploads\/2020\/08\/image-11.png 605w, http:\/\/blog.nosland.com\/wp-content\/uploads\/2020\/08\/image-11-300x69.png 300w\" sizes=\"(max-width: 605px) 100vw, 605px\" \/><\/figure>\n\n\n\n<p>Enfin on donne un titre dans la derni\u00e8re partie\u00a0en cliquant sur l\u2019ic\u00f4ne\u00a0:<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" width=\"78\" height=\"65\" src=\"http:\/\/blog.nosland.com\/wp-content\/uploads\/2020\/08\/image-12.png\" alt=\"\" class=\"wp-image-713\"\/><\/figure>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" width=\"605\" height=\"165\" src=\"http:\/\/blog.nosland.com\/wp-content\/uploads\/2020\/08\/image-13.png\" alt=\"\" class=\"wp-image-714\" srcset=\"http:\/\/blog.nosland.com\/wp-content\/uploads\/2020\/08\/image-13.png 605w, http:\/\/blog.nosland.com\/wp-content\/uploads\/2020\/08\/image-13-300x82.png 300w\" sizes=\"(max-width: 605px) 100vw, 605px\" \/><\/figure>\n\n\n\n<p>Et une fois fini, on clique sur la fl\u00e8che en haut \u00e0 gauche\u00a0:<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" width=\"95\" height=\"51\" src=\"http:\/\/blog.nosland.com\/wp-content\/uploads\/2020\/08\/image-14.png\" alt=\"\" class=\"wp-image-715\"\/><\/figure>\n\n\n\n<p>On obtient donc notre graphique sur notre tableau de bord (dashboard)<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" width=\"605\" height=\"310\" src=\"http:\/\/blog.nosland.com\/wp-content\/uploads\/2020\/08\/image-15.png\" alt=\"\" class=\"wp-image-716\" srcset=\"http:\/\/blog.nosland.com\/wp-content\/uploads\/2020\/08\/image-15.png 605w, http:\/\/blog.nosland.com\/wp-content\/uploads\/2020\/08\/image-15-300x154.png 300w\" sizes=\"(max-width: 605px) 100vw, 605px\" \/><\/figure>\n\n\n\n<p>Pour finir on enregistre notre Dashboard en cliquant sur la petite \u00ab\u00a0disquette\u00a0\u00bb\u00a0:<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" width=\"42\" height=\"55\" src=\"http:\/\/blog.nosland.com\/wp-content\/uploads\/2020\/08\/image-16.png\" alt=\"\" class=\"wp-image-717\"\/><\/figure>\n\n\n\n<p>Et voil\u00e0. L\u2019interface est assez intuitive. Il suffit de fouiller un peu. On peut ainsi faire des groupes de dashboard, faire des playlists etc\u2026 On peut cr\u00e9er des utilisateurs, g\u00e9rer des groupes d\u2019utilisateurs etc..<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Tout d\u2019abord, l\u2019interface de Grafana seule ne sert \u00e0 rien. Pour fonctionner elle a besoin d\u2019\u00eatre aliment\u00e9 par des \u00ab&nbsp;Datas&hellip;<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":[],"categories":[6],"tags":[],"_links":{"self":[{"href":"http:\/\/blog.nosland.com\/index.php?rest_route=\/wp\/v2\/posts\/698"}],"collection":[{"href":"http:\/\/blog.nosland.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"http:\/\/blog.nosland.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"http:\/\/blog.nosland.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"http:\/\/blog.nosland.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=698"}],"version-history":[{"count":3,"href":"http:\/\/blog.nosland.com\/index.php?rest_route=\/wp\/v2\/posts\/698\/revisions"}],"predecessor-version":[{"id":718,"href":"http:\/\/blog.nosland.com\/index.php?rest_route=\/wp\/v2\/posts\/698\/revisions\/718"}],"wp:attachment":[{"href":"http:\/\/blog.nosland.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=698"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/blog.nosland.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=698"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/blog.nosland.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=698"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}