{"id":5662,"date":"2014-08-05T16:35:35","date_gmt":"2014-08-05T14:35:35","guid":{"rendered":"http:\/\/blog.zhaw.ch\/icclab\/?p=5662"},"modified":"2014-08-05T17:41:24","modified_gmt":"2014-08-05T15:41:24","slug":"profiling-the-ceilometer-api-to-identify-performance-bottlenecks","status":"publish","type":"post","link":"https:\/\/blog.zhaw.ch\/icclab\/profiling-the-ceilometer-api-to-identify-performance-bottlenecks\/","title":{"rendered":"Profiling the Ceilometer API to Identify Performance Bottlenecks"},"content":{"rendered":"<p>We are using <a href=\"https:\/\/wiki.openstack.org\/wiki\/Ceilometer\">ceilometer<\/a> to collect data energy from our servers. As noted <a href=\"http:\/\/blog.zhaw.ch\/icclab\/ceilometer-performance-issues\/\">previously<\/a> we were having some performance issues and we needed to investigate further. In this blog post we will cover our approach to performing profiling on <a href=\"http:\/\/docs.openstack.org\/developer\/ceilometer\/webapi\/v2.html\">ceilometer API <\/a>to determine where the problems arose.<\/p>\n<p>Of course, the first step was to take a look at the log files (in <code>\/var\/log\/ceilometer-all.log<\/code>); as there was nothing unusual in there, we decided to perform profiling of the code.<\/p>\n<p><!--more--><\/p>\n<p>The ceilometer API is served via a simple <a href=\"https:\/\/docs.python.org\/2\/library\/wsgiref.html\">WSGI<\/a> server which uses the <a href=\"http:\/\/pecan.readthedocs.org\/en\/latest\/\">pecan<\/a> framework to support routing of requests, simple authentication and configuration of the API. In order to profile the code, it is necessary to intercept the request handling in the WSGI server and add the profilng code there. To do this, we needed to create a new WSGIRequestHandler which activated profiling (using <a href=\"https:\/\/docs.python.org\/2\/library\/profile.html\">cProfile<\/a>), passed the request to the default handler before deactivating handling and providing a return value. The output of the profiling is then stored in \u00a0<code>\/tmp\/profile<\/code>. The code below shows how this was done.<\/p>\n<p><code>\/ceilometer\/api\/app.py:153<\/code><\/p>\n<pre><code>\r\nclass TestHandler(simple_server.WSGIRequestHandler):\r\n    def handle(self, *args, **kwargs):\r\n        LOG.info('Handling basic request.')\r\n        import cProfile\r\n        profile = cProfile.Profile()\r\n        profile.enable()\r\n        temp = simple_server.WSGIRequestHandler.handle(self, *args, **kwargs)\r\n        profile.disable()\r\n        profile.dump_stats('\/tmp\/profile')\r\n        return temp\r\n\r\ndef build_server():\r\n    # Build the WSGI app\r\n    root = VersionSelectorApplication()\r\n    # Create the WSGI server and start it\r\n    host, port = cfg.CONF.api.host, cfg.CONF.api.port\r\n    server_cls = get_server_cls(host)\r\n    srv = simple_server.make_server(host, port, root, server_cls, TestHandler)\r\n<\/code><\/pre>\n<p>Profiling was then active on each call to the ceilometer API. We then made a call to the API (<code>ceilometer samples-list <\/code>in this case) and the profiling data for the call is generated. We used <a href=\"http:\/\/www.pythonforbeginners.com\/systems-programming\/how-to-use-fabric-in-python\/\">Fabric<\/a> to access the server via ssh and download the file to local machine. Then <a href=\"http:\/\/ymichael.com\/2014\/03\/08\/profiling-python-with-cprofile.html\">cprofilev<\/a> is used to display the results of the profiling such that they are visible within a browser. The results are below.<\/p>\n<p style=\"text-align: center\"><a href=\"http:\/\/blog.zhaw.ch\/icclab\/files\/2014\/08\/Screenshot-from-2014-08-05-144104.png\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-medium wp-image-5665\" src=\"http:\/\/blog.zhaw.ch\/icclab\/files\/2014\/08\/Screenshot-from-2014-08-05-144104-296x300.png\" alt=\"Screenshot from 2014-08-05 14:41:04\" width=\"296\" height=\"300\" srcset=\"https:\/\/blog.zhaw.ch\/icclab\/files\/2014\/08\/Screenshot-from-2014-08-05-144104-296x300.png 296w, https:\/\/blog.zhaw.ch\/icclab\/files\/2014\/08\/Screenshot-from-2014-08-05-144104-1013x1024.png 1013w, https:\/\/blog.zhaw.ch\/icclab\/files\/2014\/08\/Screenshot-from-2014-08-05-144104.png 1057w\" sizes=\"auto, (max-width: 296px) 100vw, 296px\" \/><\/a><\/p>\n<p>In our specific case, we found a problem with our DNS settings which manifested in the <code>_socket.gethostbyaddr()<\/code> call &#8211; while this may be a little bit of a heavy approach to determining this, it was useful for us to be able to instrument ceilometer in case of any performance issues.<\/p>\n<div class=\"pt-sm\">Schlagw\u00f6rter: <a href=\"https:\/\/blog.zhaw.ch\/icclab\/tag\/ceilometer\/\">Ceilometer<\/a>, <a href=\"https:\/\/blog.zhaw.ch\/icclab\/tag\/cprofile\/\">cprofile<\/a>, <a href=\"https:\/\/blog.zhaw.ch\/icclab\/tag\/openstack\/\">openstack<\/a>, <a href=\"https:\/\/blog.zhaw.ch\/icclab\/tag\/profiling\/\">profiling<\/a>, <a href=\"https:\/\/blog.zhaw.ch\/icclab\/tag\/python\/\">Python<\/a>, <a href=\"https:\/\/blog.zhaw.ch\/icclab\/tag\/telemetry\/\">telemetry<\/a><br><\/div>","protected":false},"excerpt":{"rendered":"<p>We are using ceilometer to collect data energy from our servers. As noted previously we were having some performance issues and we needed to investigate further. In this blog post we will cover our approach to performing profiling on ceilometer API to determine where the problems arose. Of course, the first step was to take [&hellip;]<\/p>\n","protected":false},"author":101,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"ngg_post_thumbnail":0,"footnotes":""},"categories":[5,15,19,20],"tags":[65,441,240,440,273,439],"features":[],"class_list":["post-5662","post","type-post","status-publish","format-standard","hentry","category-articles","category-howtos","category-news","category-open-source","tag-ceilometer","tag-cprofile","tag-openstack","tag-profiling","tag-python","tag-telemetry"],"yoast_head":"<!-- This site is optimized with the Yoast SEO Premium plugin v27.2 (Yoast SEO v27.2) - https:\/\/yoast.com\/product\/yoast-seo-premium-wordpress\/ -->\n<title>Profiling the Ceilometer API to Identify Performance Bottlenecks - Service Engineering (ICCLab &amp; SPLab)<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/blog.zhaw.ch\/icclab\/profiling-the-ceilometer-api-to-identify-performance-bottlenecks\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Profiling the Ceilometer API to Identify Performance Bottlenecks\" \/>\n<meta property=\"og:description\" content=\"We are using ceilometer to collect data energy from our servers. As noted previously we were having some performance issues and we needed to investigate further. In this blog post we will cover our approach to performing profiling on ceilometer API to determine where the problems arose. Of course, the first step was to take [&hellip;]\" \/>\n<meta property=\"og:url\" content=\"https:\/\/blog.zhaw.ch\/icclab\/profiling-the-ceilometer-api-to-identify-performance-bottlenecks\/\" \/>\n<meta property=\"og:site_name\" content=\"Service Engineering (ICCLab &amp; SPLab)\" \/>\n<meta property=\"article:published_time\" content=\"2014-08-05T14:35:35+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2014-08-05T15:41:24+00:00\" \/>\n<meta property=\"og:image\" content=\"http:\/\/blog.zhaw.ch\/icclab\/files\/2014\/08\/Screenshot-from-2014-08-05-144104-296x300.png\" \/>\n<meta name=\"author\" content=\"Bruno Grazioli\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Bruno Grazioli\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"2 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\/\/blog.zhaw.ch\/icclab\/profiling-the-ceilometer-api-to-identify-performance-bottlenecks\/#article\",\"isPartOf\":{\"@id\":\"https:\/\/blog.zhaw.ch\/icclab\/profiling-the-ceilometer-api-to-identify-performance-bottlenecks\/\"},\"author\":{\"name\":\"Bruno Grazioli\",\"@id\":\"https:\/\/blog.zhaw.ch\/icclab\/#\/schema\/person\/769a2455bfa3cbcc87857218f19abeba\"},\"headline\":\"Profiling the Ceilometer API to Identify Performance Bottlenecks\",\"datePublished\":\"2014-08-05T14:35:35+00:00\",\"dateModified\":\"2014-08-05T15:41:24+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/blog.zhaw.ch\/icclab\/profiling-the-ceilometer-api-to-identify-performance-bottlenecks\/\"},\"wordCount\":302,\"commentCount\":0,\"image\":{\"@id\":\"https:\/\/blog.zhaw.ch\/icclab\/profiling-the-ceilometer-api-to-identify-performance-bottlenecks\/#primaryimage\"},\"thumbnailUrl\":\"http:\/\/blog.zhaw.ch\/icclab\/files\/2014\/08\/Screenshot-from-2014-08-05-144104-296x300.png\",\"keywords\":[\"Ceilometer\",\"cprofile\",\"openstack\",\"profiling\",\"Python\",\"telemetry\"],\"articleSection\":[\"Articles\",\"HowTos\",\"News\",\"Open Source\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\/\/blog.zhaw.ch\/icclab\/profiling-the-ceilometer-api-to-identify-performance-bottlenecks\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/blog.zhaw.ch\/icclab\/profiling-the-ceilometer-api-to-identify-performance-bottlenecks\/\",\"url\":\"https:\/\/blog.zhaw.ch\/icclab\/profiling-the-ceilometer-api-to-identify-performance-bottlenecks\/\",\"name\":\"Profiling the Ceilometer API to Identify Performance Bottlenecks - Service Engineering (ICCLab &amp; SPLab)\",\"isPartOf\":{\"@id\":\"https:\/\/blog.zhaw.ch\/icclab\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/blog.zhaw.ch\/icclab\/profiling-the-ceilometer-api-to-identify-performance-bottlenecks\/#primaryimage\"},\"image\":{\"@id\":\"https:\/\/blog.zhaw.ch\/icclab\/profiling-the-ceilometer-api-to-identify-performance-bottlenecks\/#primaryimage\"},\"thumbnailUrl\":\"http:\/\/blog.zhaw.ch\/icclab\/files\/2014\/08\/Screenshot-from-2014-08-05-144104-296x300.png\",\"datePublished\":\"2014-08-05T14:35:35+00:00\",\"dateModified\":\"2014-08-05T15:41:24+00:00\",\"author\":{\"@id\":\"https:\/\/blog.zhaw.ch\/icclab\/#\/schema\/person\/769a2455bfa3cbcc87857218f19abeba\"},\"breadcrumb\":{\"@id\":\"https:\/\/blog.zhaw.ch\/icclab\/profiling-the-ceilometer-api-to-identify-performance-bottlenecks\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/blog.zhaw.ch\/icclab\/profiling-the-ceilometer-api-to-identify-performance-bottlenecks\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/blog.zhaw.ch\/icclab\/profiling-the-ceilometer-api-to-identify-performance-bottlenecks\/#primaryimage\",\"url\":\"https:\/\/blog.zhaw.ch\/icclab\/files\/2014\/08\/Screenshot-from-2014-08-05-144104.png\",\"contentUrl\":\"https:\/\/blog.zhaw.ch\/icclab\/files\/2014\/08\/Screenshot-from-2014-08-05-144104.png\",\"width\":1057,\"height\":1068},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/blog.zhaw.ch\/icclab\/profiling-the-ceilometer-api-to-identify-performance-bottlenecks\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Startseite\",\"item\":\"https:\/\/blog.zhaw.ch\/icclab\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Profiling the Ceilometer API to Identify Performance Bottlenecks\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/blog.zhaw.ch\/icclab\/#website\",\"url\":\"https:\/\/blog.zhaw.ch\/icclab\/\",\"name\":\"Service Engineering (ICCLab &amp; SPLab)\",\"description\":\"A Blog of the ZHAW Zurich University of Applied Sciences\",\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/blog.zhaw.ch\/icclab\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Person\",\"@id\":\"https:\/\/blog.zhaw.ch\/icclab\/#\/schema\/person\/769a2455bfa3cbcc87857218f19abeba\",\"name\":\"Bruno Grazioli\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/secure.gravatar.com\/avatar\/07d475be0415d5914aa49599b3295e4d972f971e46f5d7ab89d474327ab7b5f0?s=96&d=mm&r=g\",\"url\":\"https:\/\/secure.gravatar.com\/avatar\/07d475be0415d5914aa49599b3295e4d972f971e46f5d7ab89d474327ab7b5f0?s=96&d=mm&r=g\",\"contentUrl\":\"https:\/\/secure.gravatar.com\/avatar\/07d475be0415d5914aa49599b3295e4d972f971e46f5d7ab89d474327ab7b5f0?s=96&d=mm&r=g\",\"caption\":\"Bruno Grazioli\"},\"url\":\"https:\/\/blog.zhaw.ch\/icclab\/author\/gaea\/\"}]}<\/script>\n<!-- \/ Yoast SEO Premium plugin. -->","yoast_head_json":{"title":"Profiling the Ceilometer API to Identify Performance Bottlenecks - Service Engineering (ICCLab &amp; SPLab)","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/blog.zhaw.ch\/icclab\/profiling-the-ceilometer-api-to-identify-performance-bottlenecks\/","og_locale":"en_US","og_type":"article","og_title":"Profiling the Ceilometer API to Identify Performance Bottlenecks","og_description":"We are using ceilometer to collect data energy from our servers. As noted previously we were having some performance issues and we needed to investigate further. In this blog post we will cover our approach to performing profiling on ceilometer API to determine where the problems arose. Of course, the first step was to take [&hellip;]","og_url":"https:\/\/blog.zhaw.ch\/icclab\/profiling-the-ceilometer-api-to-identify-performance-bottlenecks\/","og_site_name":"Service Engineering (ICCLab &amp; SPLab)","article_published_time":"2014-08-05T14:35:35+00:00","article_modified_time":"2014-08-05T15:41:24+00:00","og_image":[{"url":"http:\/\/blog.zhaw.ch\/icclab\/files\/2014\/08\/Screenshot-from-2014-08-05-144104-296x300.png","type":"","width":"","height":""}],"author":"Bruno Grazioli","twitter_card":"summary_large_image","twitter_misc":{"Written by":"Bruno Grazioli","Est. reading time":"2 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/blog.zhaw.ch\/icclab\/profiling-the-ceilometer-api-to-identify-performance-bottlenecks\/#article","isPartOf":{"@id":"https:\/\/blog.zhaw.ch\/icclab\/profiling-the-ceilometer-api-to-identify-performance-bottlenecks\/"},"author":{"name":"Bruno Grazioli","@id":"https:\/\/blog.zhaw.ch\/icclab\/#\/schema\/person\/769a2455bfa3cbcc87857218f19abeba"},"headline":"Profiling the Ceilometer API to Identify Performance Bottlenecks","datePublished":"2014-08-05T14:35:35+00:00","dateModified":"2014-08-05T15:41:24+00:00","mainEntityOfPage":{"@id":"https:\/\/blog.zhaw.ch\/icclab\/profiling-the-ceilometer-api-to-identify-performance-bottlenecks\/"},"wordCount":302,"commentCount":0,"image":{"@id":"https:\/\/blog.zhaw.ch\/icclab\/profiling-the-ceilometer-api-to-identify-performance-bottlenecks\/#primaryimage"},"thumbnailUrl":"http:\/\/blog.zhaw.ch\/icclab\/files\/2014\/08\/Screenshot-from-2014-08-05-144104-296x300.png","keywords":["Ceilometer","cprofile","openstack","profiling","Python","telemetry"],"articleSection":["Articles","HowTos","News","Open Source"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/blog.zhaw.ch\/icclab\/profiling-the-ceilometer-api-to-identify-performance-bottlenecks\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/blog.zhaw.ch\/icclab\/profiling-the-ceilometer-api-to-identify-performance-bottlenecks\/","url":"https:\/\/blog.zhaw.ch\/icclab\/profiling-the-ceilometer-api-to-identify-performance-bottlenecks\/","name":"Profiling the Ceilometer API to Identify Performance Bottlenecks - Service Engineering (ICCLab &amp; SPLab)","isPartOf":{"@id":"https:\/\/blog.zhaw.ch\/icclab\/#website"},"primaryImageOfPage":{"@id":"https:\/\/blog.zhaw.ch\/icclab\/profiling-the-ceilometer-api-to-identify-performance-bottlenecks\/#primaryimage"},"image":{"@id":"https:\/\/blog.zhaw.ch\/icclab\/profiling-the-ceilometer-api-to-identify-performance-bottlenecks\/#primaryimage"},"thumbnailUrl":"http:\/\/blog.zhaw.ch\/icclab\/files\/2014\/08\/Screenshot-from-2014-08-05-144104-296x300.png","datePublished":"2014-08-05T14:35:35+00:00","dateModified":"2014-08-05T15:41:24+00:00","author":{"@id":"https:\/\/blog.zhaw.ch\/icclab\/#\/schema\/person\/769a2455bfa3cbcc87857218f19abeba"},"breadcrumb":{"@id":"https:\/\/blog.zhaw.ch\/icclab\/profiling-the-ceilometer-api-to-identify-performance-bottlenecks\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/blog.zhaw.ch\/icclab\/profiling-the-ceilometer-api-to-identify-performance-bottlenecks\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/blog.zhaw.ch\/icclab\/profiling-the-ceilometer-api-to-identify-performance-bottlenecks\/#primaryimage","url":"https:\/\/blog.zhaw.ch\/icclab\/files\/2014\/08\/Screenshot-from-2014-08-05-144104.png","contentUrl":"https:\/\/blog.zhaw.ch\/icclab\/files\/2014\/08\/Screenshot-from-2014-08-05-144104.png","width":1057,"height":1068},{"@type":"BreadcrumbList","@id":"https:\/\/blog.zhaw.ch\/icclab\/profiling-the-ceilometer-api-to-identify-performance-bottlenecks\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Startseite","item":"https:\/\/blog.zhaw.ch\/icclab\/"},{"@type":"ListItem","position":2,"name":"Profiling the Ceilometer API to Identify Performance Bottlenecks"}]},{"@type":"WebSite","@id":"https:\/\/blog.zhaw.ch\/icclab\/#website","url":"https:\/\/blog.zhaw.ch\/icclab\/","name":"Service Engineering (ICCLab &amp; SPLab)","description":"A Blog of the ZHAW Zurich University of Applied Sciences","potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/blog.zhaw.ch\/icclab\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Person","@id":"https:\/\/blog.zhaw.ch\/icclab\/#\/schema\/person\/769a2455bfa3cbcc87857218f19abeba","name":"Bruno Grazioli","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/secure.gravatar.com\/avatar\/07d475be0415d5914aa49599b3295e4d972f971e46f5d7ab89d474327ab7b5f0?s=96&d=mm&r=g","url":"https:\/\/secure.gravatar.com\/avatar\/07d475be0415d5914aa49599b3295e4d972f971e46f5d7ab89d474327ab7b5f0?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/07d475be0415d5914aa49599b3295e4d972f971e46f5d7ab89d474327ab7b5f0?s=96&d=mm&r=g","caption":"Bruno Grazioli"},"url":"https:\/\/blog.zhaw.ch\/icclab\/author\/gaea\/"}]}},"_links":{"self":[{"href":"https:\/\/blog.zhaw.ch\/icclab\/wp-json\/wp\/v2\/posts\/5662","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/blog.zhaw.ch\/icclab\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blog.zhaw.ch\/icclab\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blog.zhaw.ch\/icclab\/wp-json\/wp\/v2\/users\/101"}],"replies":[{"embeddable":true,"href":"https:\/\/blog.zhaw.ch\/icclab\/wp-json\/wp\/v2\/comments?post=5662"}],"version-history":[{"count":8,"href":"https:\/\/blog.zhaw.ch\/icclab\/wp-json\/wp\/v2\/posts\/5662\/revisions"}],"predecessor-version":[{"id":5671,"href":"https:\/\/blog.zhaw.ch\/icclab\/wp-json\/wp\/v2\/posts\/5662\/revisions\/5671"}],"wp:attachment":[{"href":"https:\/\/blog.zhaw.ch\/icclab\/wp-json\/wp\/v2\/media?parent=5662"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.zhaw.ch\/icclab\/wp-json\/wp\/v2\/categories?post=5662"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.zhaw.ch\/icclab\/wp-json\/wp\/v2\/tags?post=5662"},{"taxonomy":"features","embeddable":true,"href":"https:\/\/blog.zhaw.ch\/icclab\/wp-json\/wp\/v2\/features?post=5662"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}