{"id":281,"date":"2009-05-02T22:12:19","date_gmt":"2009-05-02T22:12:19","guid":{"rendered":"http:\/\/blog.milamberspace.net\/?p=281"},"modified":"2009-07-11T21:56:18","modified_gmt":"2009-07-11T20:56:18","slug":"jmeter-utiliser-sqlite-pour-traiter-les-resultats-dun-test-de-charges-par-palier","status":"publish","type":"post","link":"https:\/\/blog.milamberspace.net\/index.php\/2009\/05\/02\/jmeter-utiliser-sqlite-pour-traiter-les-resultats-dun-test-de-charges-par-palier-281.html","title":{"rendered":"JMeter : utiliser SQLite pour traiter les r\u00e9sultats d&rsquo;un test de charges par palier"},"content":{"rendered":"<p style=\"\"><a href=\"http:\/\/blog.milamberspace.net\/index.php\/2009\/05\/02\/jmeter-et-la-creation-du-rapport-de-tir-de-charges-278.html\" target=\"_self\">Dans ce billet<\/a>, j&rsquo;indique qu&rsquo;il est possible d&rsquo;utiliser SQLite pour traiter les donn\u00e9es d&rsquo;un <a href=\"http:\/\/blog.milamberspace.net\/index.php\/jmeter-tir-de-charges-par-paliers-et-exploitation-des-resultats\" target=\"_blank\">tir de charges par palier (tutoriel ici)<\/a>.<\/p>\n<p style=\"\">Voici maintenant le mode d&#8217;emploi pour utiliser SQLite afin de traiter ses r\u00e9sultats de tir JMeter.<!--more--> Tout d&rsquo;abord, pour une meilleur compr\u00e9hension voici le plan de test dans JMeter. <em>Veuillez noter les noms des contr\u00f4leurs et requ\u00eates.<\/em><\/p>\n<p style=\"\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone\" title=\"Plan de test de charges par palier\" src=\"\/wp-content\/images\/jmeter17-img\/jmeter-plan-de-test-palier.png\" alt=\"\" width=\"366\" height=\"633\" \/><\/p>\n<p style=\"\">Pour une insertion future des donn\u00e9es du fichier CSV dans une base de donn\u00e9es SQLite, il est pr\u00e9f\u00e9rable de configurer un peu le format d&rsquo;enregistrement des donn\u00e9es CSV par JMeter.<\/p>\n<p style=\"\">Dans le fichier <em>JMETER_HOME\/bin\/user.properties<\/em>, voici le format utilis\u00e9 pour cet article. Cette configuration est &lsquo;arbitraire&rsquo;, il est bien entendu possible de la personnaliser en fonction de ce que vous voulez faire (ou voir).<\/p>\n<pre style=\"\">jmeter.save.saveservice.output_format=csv<\/pre>\n<pre style=\"\">jmeter.save.saveservice.data_type=false<\/pre>\n<pre style=\"\">jmeter.save.saveservice.label=true<\/pre>\n<pre style=\"\">jmeter.save.saveservice.response_code=true<\/pre>\n<pre style=\"\">jmeter.save.saveservice.response_data=false<\/pre>\n<pre style=\"\">jmeter.save.saveservice.response_message=false<\/pre>\n<pre style=\"\">jmeter.save.saveservice.successful=true<\/pre>\n<pre style=\"\">jmeter.save.saveservice.thread_name=true<\/pre>\n<pre style=\"\">jmeter.save.saveservice.time=true<\/pre>\n<pre style=\"\">jmeter.save.saveservice.bytes=true<\/pre>\n<pre style=\"\">jmeter.save.saveservice.url=false<\/pre>\n<pre style=\"\">jmeter.save.saveservice.timestamp_format=yyyy-MM-dd;HH:mm:ss<\/pre>\n<pre style=\"\">jmeter.save.saveservice.default_delimiter=;<\/pre>\n<pre style=\"\">jmeter.save.saveservice.print_field_names=false<\/pre>\n<pre style=\"\">jmeter.save.saveservice.hostname=true<\/pre>\n<pre style=\"\">jmeter.save.saveservice.thread_counts=true<\/pre>\n<p style=\"\">Apr\u00e8s son test de charge, le fichiers de r\u00e9sultats \u00e0 cette forme :<\/p>\n<pre style=\"\">\"2009-04-28;22:01:47\";146;Requ\u00eate HTTP 01_Accueil;200;\"Groupe d'unit\u00e9s 1; 1-1\";true;7347;11;11;130;ubuntusvr<\/pre>\n<pre style=\"\">\"2009-04-28;22:01:47\";38;Requ\u00eate HTTP 01_Accueil;200;\"Groupe d'unit\u00e9s 1; 1-2\";true;7347;11;11;34;ubuntusvr<\/pre>\n<pre style=\"\">\"2009-04-28;22:01:47\";16;Requ\u00eate HTTP 01_Accueil;200;\"Groupe d'unit\u00e9s 1; 1-3\";true;7347;12;12;13;ubuntusvr<\/pre>\n<pre style=\"\">\"2009-04-28;22:01:48\";12;Requ\u00eate HTTP 01_Accueil;200;\"Groupe d'unit\u00e9s 1; 1-4\";true;7347;13;13;7;ubuntusvr<\/pre>\n<pre style=\"\">\"2009-04-28;22:01:48\";11;Requ\u00eate HTTP 01_Accueil;200;\"Groupe d'unit\u00e9s 1; 1-5\";true;7347;15;15;7;ubuntusvr<\/pre>\n<pre style=\"\">\"2009-04-28;22:01:49\";11;Requ\u00eate HTTP 01_Accueil;200;\"Groupe d'unit\u00e9s 1; 1-6\";true;7347;15;15;8;ubuntusvr<\/pre>\n<pre style=\"\">\"2009-04-28;22:01:49\";12;Requ\u00eate HTTP 01_Accueil;200;\"Groupe d'unit\u00e9s 1; 1-7\";true;7347;17;17;8;ubuntusvr<\/pre>\n<pre style=\"\">\"2009-04-28;22:01:49\";11;Requ\u00eate HTTP 01_Accueil;200;\"Groupe d'unit\u00e9s 1; 1-8\";true;7347;17;17;9;ubuntusvr<\/pre>\n<pre style=\"\">\"2009-04-28;22:01:50\";13;Requ\u00eate HTTP 01_Accueil;200;\"Groupe d'unit\u00e9s 1; 1-9\";true;7347;18;18;7;ubuntusvr<\/pre>\n<p style=\"\"><em><span style=\"text-decoration: underline;\">On notera les points suivants :<\/span><\/em><\/p>\n<p style=\"\">La date et l&rsquo;heure sont entre guillemets \u00e0 cause du point-virgule ajout\u00e9 dans le format du timestamp dans user.properties : <strong>\u00ab\u00a02009-04-28;22:01:47\u00a0\u00bb<\/strong>. Ce point-virgule va nous permettre de sectionner la date et l&rsquo;heure <em>(m\u00eame si en r\u00e9alit\u00e9, SQLite3 n&rsquo;en pas vraiment besoin, mais bon&#8230;)<\/em><\/p>\n<p style=\"\">Le nom du groupe d&rsquo;unit\u00e9s (thread name) est aussi entre guillemets et avec un point-virgule qui s\u00e9pare le nom (celui dans l&rsquo;arbre JMeter) et le num\u00e9ro du thread ex\u00e9cutant. Car j&rsquo;ai pris soin de mettre un point-virgule en fin de nom.<\/p>\n<p style=\"\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone\" title=\"Nom du groupe dunit\u00e9s avec point-virgule \u00e0 la fin\" src=\"\/wp-content\/images\/jmeter17-img\/jmeter-nom-gu.png\" alt=\"\" width=\"210\" height=\"91\" \/><\/p>\n<p style=\"\">Dans ces deux champs, les guillemets \u00ab nous g\u00eanent \u00bb, il faut donc les supprimer. Pour cela, soit on \u00e9dite le fichier et on fait un &lsquo;remplac\u00e9 global&rsquo; (\u00a0\u00bb par vide), soit on passe par la commande SED disponible sous Unix ou Windows.<\/p>\n<pre style=\"\">cat Resultats.csv | sed \"s\/\\\"\/\/g\" &gt; PourInsertion.csv<\/pre>\n<p style=\"\">Voil\u00e0 le fichier CSV est pr\u00eat pour insertion dans la base SQLite.<\/p>\n<p style=\"\">La cr\u00e9ation de la base de donn\u00e9es se fait simplement dans le lancement de SQLite.<\/p>\n<pre style=\"\">$ sqlite3 mabase.db<\/pre>\n<p style=\"\">Ensuite au prompt <strong>&lsquo;sqlite&gt;&rsquo;<\/strong> on peut cr\u00e9er la table qui va recevoir les donn\u00e9es.<\/p>\n<pre style=\"\">sqlite&gt; CREATE TABLE resultats (date TEXT,heure TEXT,temps REAL,libelle TEXT,code TEXT,nomTG TEXT,\r\nnumTG TEXT,succes TEXT,octets INTEGER, actifTG INTEGER, nbTG INTEGER,latence REAL,hostname TEXT);<\/pre>\n<p style=\"\">Il ne reste plus qu&rsquo;\u00e0 indiquer \u00e0 SQLite le s\u00e9parateur \u00e0 utiliser (ici le point-virgule), puis faire l&rsquo;import.<\/p>\n<pre style=\"\">sqlite&gt; .separator ;<\/pre>\n<pre style=\"\">sqlite&gt; .import PourInsert.csv resultats<\/pre>\n<p style=\"\"><strong><em>Et voil\u00e0, les donn\u00e9es sont import\u00e9es.<\/em><\/strong><\/p>\n<p style=\"\"><span style=\"text-decoration: underline;\">On peut commencer \u00e0 jouer avec des requ\u00eates SQL :<\/span><\/p>\n<p style=\"\"><em>(je n&rsquo;explique pas comment faire des requ\u00eates SQL, si besoin, voir <a title=\"Documentation SQLite\" href=\"http:\/\/www.sqlite.org\/docs.html\" target=\"_blank\">la documentation de SQLite<\/a>)<\/em><\/p>\n<p style=\"\"><strong><span style=\"text-decoration: underline;\">Compter le nombre de r\u00e9sultats (lignes) :<\/span><\/strong><\/p>\n<pre style=\"\">sqlite&gt; <strong><span style=\"color: #000080;\">SELECT COUNT(*) FROM resultats;<\/span><\/strong><\/pre>\n<pre style=\"\">400249<\/pre>\n<p style=\"\"><em>On se mets en mode headers ON et column sur SQLite pour faciliter la pr\u00e9sentation des r\u00e9sultats de requ\u00eates.<\/em><\/p>\n<pre style=\"\">sqlite&gt; .headers on<\/pre>\n<pre style=\"\">sqlite&gt; .mode column<\/pre>\n<p style=\"\"><strong><span style=\"text-decoration: underline;\">Moyenne des temps de r\u00e9ponses par libell\u00e9s :<\/span><\/strong><\/p>\n<pre style=\"\">sqlite&gt; <strong><span style=\"color: #000080;\">SELECT libelle, COUNT(libelle), AVG(temps) FROM resultats GROUP BY libelle ORDER BY libelle;<\/span><\/strong><\/pre>\n<pre style=\"\">libelle                          COUNT(libelle)  AVG(temps)<\/pre>\n<pre style=\"\">-------------------------------  --------------  ----------------<\/pre>\n<pre style=\"\">Contr\u00f4leur Transaction (Login)  1500            8049.02333333333<\/pre>\n<pre style=\"\">Contr\u00f4leur Transaction Cr\u00e9ati   20725           60324.5965741858<\/pre>\n<pre style=\"\">Contr\u00f4leur Transaction Recherc  21130           120353.20241363<\/pre>\n<pre style=\"\">Requ\u00eate HTTP 01_Accueil         1500            11.66<\/pre>\n<pre style=\"\">Requ\u00eate HTTP 02_Connexion       1500            11.7486666666667<\/pre>\n<pre style=\"\">Requ\u00eate HTTP 03_Accueil Recher  22008           10.4412940748819<\/pre>\n<pre style=\"\">Requ\u00eate HTTP 04_Liste Resultat  21150           12.8220330969267<\/pre>\n<pre style=\"\">Requ\u00eate HTTP 05_Fiche Client    21140           13.4635288552507<\/pre>\n<pre style=\"\">Requ\u00eate HTTP 06_Creation Nouve  21030           10.5896338563956<\/pre>\n<pre style=\"\">Requ\u00eate HTTP 07_Saisie Adresse  20952           11.125190912562<\/pre>\n<pre style=\"\">Requ\u00eate HTTP 08_Verification i  20878           11.4587125203564<\/pre>\n<pre style=\"\">Requ\u00eate HTTP 09_Validation con  20799           11.729265830088<\/pre>\n<pre style=\"\">Requ\u00eate HTTP 12_Ping            205937          13.7524776994906<\/pre>\n<p style=\"\">\n<p style=\"\"><strong><span style=\"text-decoration: underline;\">Moyenne des temps de r\u00e9ponses pour seulement les libell\u00e9s avec \u00ab Requ\u00eate \u00bb, \u00e0 partir de 300 secondes (fin de ma p\u00e9riode de mont\u00e9e en charge) et jusqu&rsquo;\u00e0 2100 secondes (fin du palier 1) :<br \/>\n<\/span><\/strong><\/p>\n<pre style=\"\">sqlite&gt; <strong><span style=\"color: #000080;\">SELECT nomTG, libelle, avg(temps), count(temps) FROM resultats WHERE libelle LIKE 'Requ\u00eate%' AND<\/span><\/strong><\/pre>\n<pre style=\"\"><strong><span style=\"color: #000080;\"> strftime(\"%H:%M:%S\", heure) &gt;= (select min(strftime(\"%H:%M:%S\", heure, '+300 seconds')) from resultats) AND <\/span><\/strong><\/pre>\n<pre style=\"\"><strong><span style=\"color: #000080;\">strftime(\"%H:%M:%S\", heure) &lt; (select min(strftime(\"%H:%M:%S\", heure, '+2100 seconds')) from resultats) <\/span><\/strong><\/pre>\n<pre style=\"\"><strong><span style=\"color: #000080;\">GROUP BY libelle, nomTG ORDER BY nomTG, heure ASC LIMIT 100;<\/span><\/strong><\/pre>\n<pre style=\"\">nomTG               libelle                   avg(temps)        count(temps)<\/pre>\n<pre style=\"\">------------------  ------------------------  ----------------  ------------<\/pre>\n<pre style=\"\">Groupe d'unit\u00e9s 1  Requ\u00eate HTTP 01_Accueil  8.61538461538461  13<\/pre>\n<pre style=\"\">Groupe d'unit\u00e9s 1  Requ\u00eate HTTP 02_Connexi  9.04347826086956  23<\/pre>\n<pre style=\"\">Groupe d'unit\u00e9s 1  Requ\u00eate HTTP 03_Accueil  9.0597121023636   5627<\/pre>\n<pre style=\"\">Groupe d'unit\u00e9s 1  Requ\u00eate HTTP 04_Liste R  10.1990411931818  5632<\/pre>\n<pre style=\"\">Groupe d'unit\u00e9s 1  Requ\u00eate HTTP 05_Fiche C  10.3475252794039  5637<\/pre>\n<pre style=\"\">Groupe d'unit\u00e9s 1  Requ\u00eate HTTP 06_Creatio  9.18982456140351  5700<\/pre>\n<pre style=\"\">Groupe d'unit\u00e9s 1  Requ\u00eate HTTP 07_Saisie   9.10892825820032  5701<\/pre>\n<pre style=\"\">Groupe d'unit\u00e9s 1  Requ\u00eate HTTP 08_Verific  8.85002631117348  5701<\/pre>\n<pre style=\"\">Groupe d'unit\u00e9s 1  Requ\u00eate HTTP 09_Validat  9.96772496053324  5701<\/pre>\n<pre style=\"\">Groupe d'unit\u00e9s 1  Requ\u00eate HTTP 12_Ping     10.6768418636677  56641<\/pre>\n<p style=\"\"><strong><span style=\"text-decoration: underline;\">Moyenne des temps de r\u00e9ponses par minute (pour seulement les requ\u00eates) :<\/span><\/strong><\/p>\n<pre style=\"\">sqlite&gt; <strong><span style=\"color: #000080;\">SELECT strftime(\"%H:%M\",heure) AS Heure, AVG(temps) AS Temps FROM resultats WHERE libelle LIKE 'Requ\u00eate%' <\/span><\/strong><\/pre>\n<pre style=\"\"><strong><span style=\"color: #000080;\">GROUP BY strftime(\"%H:%M\",heure) ORDER BY heure ASC;<\/span><\/strong><\/pre>\n<pre style=\"\">Heure       Temps<\/pre>\n<pre style=\"\">----------  ----------------<\/pre>\n<pre style=\"\">22:01       14.8518518518519<\/pre>\n<pre style=\"\">22:02       11.0076452599388<\/pre>\n<pre style=\"\">22:03       10.2652274479568<\/pre>\n<pre style=\"\">22:04       12.0887068044175<\/pre>\n<pre style=\"\">22:05       9.68851303735025<\/pre>\n<pre style=\"\">[...]<\/pre>\n<pre style=\"\">23:21       10.9501897533207<\/pre>\n<pre style=\"\">23:22       8.98496240601504<\/pre>\n<pre style=\"\">23:23       8.85897435897436<\/pre>\n<p style=\"\"><strong>Passons aux choses un peu plus s\u00e9rieuses : les tables pivots :<\/strong><\/p>\n<p style=\"\"><strong><span style=\"text-decoration: underline;\">Moyenne des temps de r\u00e9ponses par palier et par requ\u00eate : <\/span><\/strong><\/p>\n<pre style=\"\">sqlite&gt; <strong><span style=\"color: #000080;\">SELECT libelle, COUNT(temps) AS 'Nb Test', AVG(CASE WHEN nbTG = 750 THEN temps END) AS 'Palier 1', <\/span><\/strong><\/pre>\n<pre style=\"\"><strong><span style=\"color: #000080;\">AVG(CASE WHEN nbTG = 1500 THEN temps END) AS 'Palier 2', AVG(temps) as 'Moy. Temps' FROM resultats <\/span><\/strong><\/pre>\n<pre style=\"\"><strong><span style=\"color: #000080;\">WHERE libelle LIKE 'Requ\u00eate%' GROUP BY libelle ORDER BY libelle ASC LIMIT 100;<\/span><\/strong><\/pre>\n<pre style=\"\">libelle                   Nb Test     Palier 1    Palier 2    Moy. Temps<\/pre>\n<pre style=\"\">------------------------  ----------  ----------  ----------  ----------<\/pre>\n<pre style=\"\">Requ\u00eate HTTP 01_Accueil  1500        8.6         9.0         11.66<\/pre>\n<pre style=\"\">Requ\u00eate HTTP 02_Connexi  1500        9.14285714  11.9047619  11.7486666<\/pre>\n<pre style=\"\">Requ\u00eate HTTP 03_Accueil  22008       8.95963999  11.5854606  10.4412940<\/pre>\n<pre style=\"\">Requ\u00eate HTTP 04_Liste R  21150       10.3961495  14.6102772  12.8220330<\/pre>\n<pre style=\"\">Requ\u00eate HTTP 05_Fiche C  21140       10.6435393  15.6499867  13.4635288<\/pre>\n<pre style=\"\">Requ\u00eate HTTP 06_Creatio  21030       9.09737098  11.5930713  10.5896338<\/pre>\n<pre style=\"\">Requ\u00eate HTTP 07_Saisie   20952       9.12340011  12.4782992  11.1251909<\/pre>\n<pre style=\"\">Requ\u00eate HTTP 08_Verific  20878       8.98065683  13.1458794  11.4587125<\/pre>\n<pre style=\"\">Requ\u00eate HTTP 09_Validat  20799       9.85591098  13.1065624  11.7292658<\/pre>\n<pre style=\"\">Requ\u00eate HTTP 12_Ping     205937      11.0057996  15.6917482  13.7524776<\/pre>\n<p style=\"\">Sans entrer dans les d\u00e9tails, la notion de tables pivot avec SQLite se fait avec l&rsquo;instruction (CASE WHEN &#8230; THEN .. END). Pour plus d&rsquo;infos,<a href=\"http:\/\/softwaresalariman.blogspot.com\/2008\/05\/pivot-table-hack-in-sqlite3-and-mysql.html\" target=\"_blank\"> voir ce billet de blog.<\/a><\/p>\n<p style=\"\">Pour revenir \u00e0 mon billet (celui que vous lisez actuellement), les tableaux sont affich\u00e9s directement par SQLite, mais comment faire ? pour les avoir dans son tableur pr\u00e9f\u00e9r\u00e9 : pour cela, il suffit d&rsquo;exporter les tableaux dans un fichier au format CSV.<\/p>\n<p style=\"\">Pour cela, on utilise les commandes SQLite suivantes :<\/p>\n<pre style=\"\">sqlite&gt; .mode tabs<\/pre>\n<pre style=\"\">sqlite&gt; .header off<\/pre>\n<pre style=\"\">sqlite&gt; .output mareq.csv<\/pre>\n<pre style=\"\">sqlite&gt; SELECT strftime(\"%H:%M\",heure) AS Heure, AVG(temps) AS Temps FROM resultats WHERE libelle LIKE 'Requ\u00eate%'<\/pre>\n<pre style=\"\">GROUP BY strftime(\"%H:%M\",heure) ORDER BY heure ASC;<\/pre>\n<p style=\"\">Le fichier mareq.csv peut \u00eatre directement ouvert par son tableur. Ce qui donnera ce graphique.<\/p>\n<p style=\"\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone\" title=\"Exemple de graphique de r\u00e9sultats dun tir par palier\" src=\"\/wp-content\/images\/jmeter17-img\/jmeter-graph-results.png\" alt=\"\" width=\"589\" height=\"369\" \/><\/p>\n<p style=\"\">Si on reprend la requ\u00eate &lsquo;pivot&rsquo;, on obtient rapidement le tableau suivant et son graphique associ\u00e9.<\/p>\n<p style=\"\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone\" title=\"Tableau de r\u00e9sultats\" src=\"\/wp-content\/images\/jmeter17-img\/jmeter-tableau-resultats.png\" alt=\"\" width=\"486\" height=\"178\" \/><\/p>\n<p style=\"\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone\" title=\"Graphique du tableau pivot\" src=\"\/wp-content\/images\/jmeter17-img\/jmeter-autre-graphique-resultats.png\" alt=\"\" width=\"608\" height=\"355\" \/><\/p>\n<p style=\"\"><em>Pour conclure, merci \u00e0 SQLite. M\u00eame si c&rsquo;est pas du \u00ab clic-next \u00bb, c&rsquo;est rapide pour faire le &lsquo;tri&rsquo; dans ses r\u00e9sultats \u00e0 condition d&rsquo;avoir quelques bonnes notions de SQL.<\/em><\/p>\n<p style=\"\">.\/<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Dans ce billet, j&rsquo;indique qu&rsquo;il est possible d&rsquo;utiliser SQLite pour traiter les donn\u00e9es d&rsquo;un tir de charges par palier (tutoriel ici). Voici maintenant le mode d&#8217;emploi pour utiliser SQLite afin de traiter ses r\u00e9sultats de tir JMeter.<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[32,33,34],"tags":[330,175,174,59],"class_list":["post-281","post","type-post","status-publish","format-standard","hentry","category-apache","category-jmeter","category-tests-de-charges","tag-jmeter","tag-rapport","tag-sqlite","tag-tir-de-charges"],"_links":{"self":[{"href":"https:\/\/blog.milamberspace.net\/index.php\/wp-json\/wp\/v2\/posts\/281","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/blog.milamberspace.net\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blog.milamberspace.net\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blog.milamberspace.net\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/blog.milamberspace.net\/index.php\/wp-json\/wp\/v2\/comments?post=281"}],"version-history":[{"count":5,"href":"https:\/\/blog.milamberspace.net\/index.php\/wp-json\/wp\/v2\/posts\/281\/revisions"}],"predecessor-version":[{"id":383,"href":"https:\/\/blog.milamberspace.net\/index.php\/wp-json\/wp\/v2\/posts\/281\/revisions\/383"}],"wp:attachment":[{"href":"https:\/\/blog.milamberspace.net\/index.php\/wp-json\/wp\/v2\/media?parent=281"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.milamberspace.net\/index.php\/wp-json\/wp\/v2\/categories?post=281"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.milamberspace.net\/index.php\/wp-json\/wp\/v2\/tags?post=281"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}