{"id":7908,"date":"2025-04-23T13:39:27","date_gmt":"2025-04-23T11:39:27","guid":{"rendered":"https:\/\/swissmakers.ch\/?p=7908"},"modified":"2025-05-12T11:16:33","modified_gmt":"2025-05-12T09:16:33","slug":"flexibly-generate-kibana-dashboards-part-2-3","status":"publish","type":"post","link":"https:\/\/swissmakers.ch\/en\/flexibel-kibana-dashboards-generieren-teil-2-3\/","title":{"rendered":"Generate Kibana dashboards flexibly - Part 2\/3"},"content":{"rendered":"\n<h2 class=\"wp-block-heading\">Einfaches Markdown-Panel<\/h2>\n\n\n\n<p>In diesem ersten Beispiel geht es nur darum, das Vorgehen zu zeigen.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Dashboard als Vorlage<\/h3>\n\n\n\n<p>Als einfaches Beispiel, das keine Datenabfragen macht, kann ein Dashboard mit einem oder mehreren Makrdown-Panels verwendet werden. In der Praxis werden Dashboards, die nur Markdown-Panels enthalten, wohl nur selten gebraucht, aber das Vorgehen l\u00e4sst sich daran gut zeigen und die Beispiele lassen sich einfach nachvollziehen. Hier der Screenshot der interaktiv erstellten Dashboardvorlage f\u00fcr das erste Beispiel:<\/p>\n\n\n<style>.kb-image7908_5f8c81-76 .kb-image-has-overlay:after{opacity:0.3;}<\/style>\n<figure class=\"wp-block-kadence-image kb-image7908_5f8c81-76 size-medium_large\"><img loading=\"lazy\" decoding=\"async\" width=\"768\" height=\"581\" src=\"https:\/\/swissmakers.ch\/wp-content\/uploads\/2025\/03\/Blog-Kibana-1-768x581.png\" alt=\"\" class=\"kb-img wp-image-7911\" srcset=\"https:\/\/swissmakers.ch\/wp-content\/uploads\/2025\/03\/Blog-Kibana-1-768x581.png 768w, https:\/\/swissmakers.ch\/wp-content\/uploads\/2025\/03\/Blog-Kibana-1-300x227.png 300w, https:\/\/swissmakers.ch\/wp-content\/uploads\/2025\/03\/Blog-Kibana-1-1024x775.png 1024w, https:\/\/swissmakers.ch\/wp-content\/uploads\/2025\/03\/Blog-Kibana-1-16x12.png 16w, https:\/\/swissmakers.ch\/wp-content\/uploads\/2025\/03\/Blog-Kibana-1.png 1480w\" sizes=\"auto, (max-width: 768px) 100vw, 768px\" \/><\/figure>\n\n\n\n<p>Dieses Dashboard wird nun exportiert und als <em>blog_beispiel1.ndjson<\/em> gespeichert.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Inputdatei mit Variablen<\/h3>\n\n\n\n<p>Da sonst auch json-Dateien verwendet werden, bietet es sich an, die Variablen ebenfalls in einer neuen json-Datei <em>blog_beispiel1_vars.json<\/em> zu definieren. Es empfiehlt sich, auch den Titel resp. Namen des Dashboards \u2013 in diesem Beispiel steht &#171;title&#187;: &#171;Blog_Beispiel1&#187; in der ndjson-Datei &#8211;&nbsp; in der Inputdatei zu definieren und dabei einen neuen Namen zu w\u00e4hlen, damit man beim Import das urspr\u00fcngliche Dashboard nicht gleich \u00fcberschreibt, falls keine neue Id generiert wird.<\/p>\n\n\n\n<p>Hier ein Beispiel des Dateiinhaltes, in dem alle Texte des Markdown-Panels definiert sind:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"json\" class=\"language-json\">{\n    \"markdown\": {\n        \"title\": \"Markdown_Titel\",\n        \"textzeilen\": [\"Textzeile1\", \"Textzeile2\",\"\ud83d\ude03\"]\n    },\n    \"dashboard_title\": \"generiertes_dashboard_blog_beispiel1\"\n}<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">Umformen der ndjson-Datei mit dem Dashboard<\/h3>\n\n\n\n<p>Danach macht man am besten eine Kopie der Datei mit dem Dashboard, hier mit dem Namen <em>blog_beispiel1.j2<\/em>.<\/p>\n\n\n\n<p>Die Zeile mit der Dashboarddefinition kopiert man nun in eine weitere, neue Datei <em>blog_beispiel1.json<\/em>, um sie besser editieren zu k\u00f6nnen. Diese neue Datei \u00f6ffnet man in VSCode und formatiert sie mit <code>&lt;ctrl&gt;&lt;alt&gt;&lt;b&gt;<\/code> (vscode-json: Beautify). Zudem k\u00f6nnen an Kommata Zeilenumbr\u00fcche und die Zeichenfolge &#8212;&#8212;&gt; angeh\u00e4ngt werden, um eine bessere \u00dcbersicht zu bekommen. Die Zeilenumbr\u00fcche und die Zeichenfolge lassen sich sp\u00e4ter wieder einfach entfernen.<\/p>\n\n\n\n<p>Der Teil der Datei mit der Definition des Markdown-Panels sieht dann etwa wie folgt aus:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"json\" class=\"language-json\">...\n    \"panelsJSON\": \"[{\\\"type\\\":\\\"visualization\\\",\n------&gt;\\\"gridData\\\":{\\\"x\\\":0,\n------&gt;\\\"y\\\":0,\n------&gt;\\\"w\\\":20,\n------&gt;\\\"h\\\":9,\n------&gt;\\\"i\\\":\\\"09747f18-d4b6-4cb0-a25e-63abf3a9cce8\\\"},\n------&gt;\\\"panelIndex\\\":\\\"09747f18-d4b6-4cb0-a25e-63abf3a9cce8\\\",\n------&gt;\\\"embeddableConfig\\\":{\\\"enhancements\\\":{\\\"dynamicActions\\\":{\\\"events\\\":[]}},\n------&gt;\\\"savedVis\\\":{\\\"id\\\":\\\"\\\",\n------&gt;\\\"title\\\":\\\"\\\",\n------&gt;\\\"description\\\":\\\"\\\",\n------&gt;\\\"type\\\":\\\"markdown\\\",\n------&gt;\\\"params\\\":{\\\"fontSize\\\":12,\n------&gt;\\\"openLinksInNewTab\\\":false,\n------&gt;\\\"markdown\\\":\\\"# Markdown_Titel\\\\n\\\\nTextzeile1\\\\n\\\\nTextzeile 2\\\\n\\\\n\ud83d\ude03\\\"},\n------&gt;\\\"uiState\\\":{},\n------&gt;\\\"data\\\":{\\\"aggs\\\":[],\n------&gt;\\\"searchSource\\\":{\\\"query\\\":{\\\"query\\\":\\\"\\\",\n------&gt;\\\"language\\\":\\\"kuery\\\"},\\\"filter\\\":[]}}}}}]\",\n    \"timeRestore\": false,\n\n        ],\n        \"timeRestore\": false,\n        \"title\": \"Blog_Beispiel1\",\n        \"version\": 2\n    },\n\u2026<\/code><\/pre>\n\n\n\n<p>Achtung, die <strong>Backslashes<\/strong> vor den Anf\u00fchrungs- und Schlusszeichen und vor Backslashes m\u00fcssen nach dem Umformen der Datei noch vorhanden sein.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Einf\u00fcgen von jinja2 Elementen<\/h3>\n\n\n\n<p>Jetzt k\u00f6nnen in der Datei <em>blog_beispiel1.json<\/em> Referenzen auf die Variablen aus der Inputdatei eingef\u00fcgt werden. Die Dokumentation zu jinja2 ist wie schon zuvor angegeben auf folgender Webseite zu finden: <a href=\"https:\/\/jinja.palletsprojects.com\/en\/stable\/templates\/\" target=\"_blank\" rel=\"noopener\">https:\/\/jinja.palletsprojects.com\/en\/stable\/templates\/<\/a>. Um den Wert eines Elementes der Inputdatei einzuf\u00fcgen, gen\u00fcgt es, den Namen der Variable in doppelten geschweiften Klammern anzugeben.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"json\" class=\"language-json\">      \"markdown\": \"# Markdown_Titel\\n\\nTextzeile1\\n\\nTextzeile 2\\n\\n\ud83d\ude03\"<\/code><\/pre>\n\n\n\n<p>muss dazu f\u00fcr die obige Inputdatei wie folgt angepasst werden:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"json\" class=\"language-json\">      \"markdown\": \"# {{ markdown.title }}\\n\\n{{ markdown.textzeilen.0 }}\\n\\n{{ markdown.textzeilen.1 }}\\n\\n{{ markdown.textzeilen.2 }}\"<\/code><\/pre>\n\n\n\n<p><code>markdown.textzeilen<\/code> ist als Array definiert und mit den Zahlen kann auf die einzelnen Arrayelemente zugegriffen werden. Die Zeile mit dem Dashboardnamen (gegen Ende der Datei vor der Versionsangabe) wird dann noch wie folgt definiert:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"json\" class=\"language-json\">        \"title\": \"{{ dashboard_title }}\",<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">Dashboard-Id l\u00f6schen<\/h3>\n\n\n\n<p>Jetzt muss man noch die Dashboard-Id in <em>blog_beispiel1.json<\/em> l\u00f6schen, da man sonst m\u00f6glicherweise einen Konflikt mit dem urspr\u00fcnglichen Dashboard und dem mit neuem Namen generierten Dashboard bekommt. Die Id steht gegen Ende der Datei nach der Angabe <code>created_at<\/code>:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"json\" class=\"language-json\">    \"created_at\": \"2024-11-26T16:56:50.240Z\",\n    \"id\": \"2d77705c-912a-4730-a565-242f6ae43475\",<\/code><\/pre>\n\n\n\n<p>Man kann einfach die Zeile mit der Id l\u00f6schen.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Formatieren als ndjson-Template<\/h3>\n\n\n\n<p>Zuerst m\u00fcssen die eingef\u00fcgten Zeilenumbr\u00fcche und Zeichenfolgen mit einem entsprechenden Replace all im Editor wieder gel\u00f6scht werden.<\/p>\n\n\n\n<p>Mit der Tastenkombination <code>&lt;ctrl&gt;&lt;alt&gt;&lt;u&gt;<\/code> (vscode-json: Uglify) kann jetzt das json in <em>blog_beisiel1.json<\/em> wieder auf eine einzelne Zeile geschrieben werden.<\/p>\n\n\n\n<p>Mit dieser Zeile ersetzt man die urspr\u00fcngliche Zeile in <em>blog_beisiel1.j2<\/em> und erh\u00e4lt so ein Template, um das Dashboard, das interaktiv erstellt wurde, neu zu generieren.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Dashboard generieren und importieren<\/h3>\n\n\n\n<p>Auf der Kommandozeile generiert man nun das neue Dashboard:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"bash\" class=\"language-bash\">jinjanate blog_beispiel1.j2 blog_beispiel1_vars.json -o generiertes_dashboard_blog_beispiel1.ndjson<\/code><\/pre>\n\n\n\n<p>In Elastic kann nun unter dem Men\u00fcpunkt \u00abManagement \u2192 Stack Management \u2192 Saved Objects\u00bb die neu generierte Dateien <em>generiertes_dashboard_blog_beispiel1.ndjson<\/em> importiert werden. Es sollte zum Import die Option \u00abCreate new objects with random Ids\u00bb ausgew\u00e4hlt werden. So erh\u00e4lt man am wenigsten Konflikte, bekommt aber allenfalls mehrere Objekte mit demselben Namen, bei denen man die alten Versionen l\u00f6schen kann. Da muss man schauen, welche Variante am einfachsten ist und ob eventuell die Ids oben nicht gel\u00f6scht werden sollen.<\/p>\n\n\n\n<p>Wenn man beim Import eine Meldung folgender Art bekommt \u00ab &#8218;generiertes_dashboard_blog_beispiel&#8216; conflicts with an existing object.\u00bb, so hat man ein Problem mit Ids und dem neuen Dashboardnamen.<\/p>\n\n\n\n<p>Das neu importierte Dashboard sieht dann genau so aus wie die Vorlage im Screenshot oben.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Mehrere Markdown Panels generieren<\/h2>\n\n\n\n<p>Ausgangspunkt ist dieselbe Vorlage wie in Beispiel 1.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Inputdatei mit Variablen<\/h3>\n\n\n\n<p>Die Inputdatei wird mit Angaben f\u00fcr mehrere Markdown-Panels erweitert. Neben dem Text f\u00fcr die Panels wird auch die Position und Gr\u00f6sse definiert. Hier die Beispieldatei <em>blog_beispiel2_vars.json<\/em>:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"json\" class=\"language-json\">{\n    \"markdown\": [\n        {\n            \"title\": \"Swissmakers\",\n            \"textzeilen\": [\n                \"Aus Freude an Technik\",\n                \"Engeneering \/ Security \/ Consulting\",\n                \"swissmakers.ch \ud83d\ude0a\"\n            ],\n            \"position\": [4,0],\n            \"groesse\": [20,8]\n        },\n        {\n            \"title\": \"Codeatelier\",\n            \"textzeilen\": [\n                \"Wir bauen deine digitale Zukunft\",\n                \"Webdesign \ud83d\udfe2 SEO \ud83d\udfe2 Webapps \ud83d\udfe2 Webshops\",\n                \"codeatelier.ch \ud83d\ude03\"\n            ],\n            \"position\": [9,9],\n            \"groesse\": [25,8]\n        },\n        {\n            \"title\": \"Swissmakers\",\n            \"textzeilen\": [\n                \"Ihre ITC-Spezialistinnen und -Spezialisten\",\n                \"Engeneering, Linux und Netzsicherheit\",\n                \"swissmakers.ch \ud83d\udc4d\"\n            ],\n            \"position\": [0,18],\n            \"groesse\": [35,8]\n        }\n    ],\n    \"dashboard_title\": \"generiertes_dashboard_blog_beispiel2\"\n}<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">Umformen der ndjson-Datei mit dem Dashboard<\/h3>\n\n\n\n<p>Wie in Beispiel 1 sollte man die Datei <em>blog_beispiel2.j2<\/em> umformen, damit sie einfacher zu \u00e4ndern ist. Damit man mehrere Markdown-Panels erh\u00e4lt, kann man im jinja2-Template in panelsJSON die Angaben f\u00fcr die Panels wiederholen. Im mit eckigen Klammern begrenzten Teil nach panelsJSON wiederholt man den ganzen Teil von <code>{\\\"type\\\":\\\"visualization\\\",<\/code> bis zu <code>\\\"filter\\\":[]}}}}}<\/code> wobei zwischen diesen Definitionen der Panels jeweils ein Komma als Trennzeichen von Array-Elementen eingef\u00fcgt werden muss. Am Ende des Arrays darf aber kein Komma mehr stehen. Das Ganze kann in einer ersten Variante direkt im Editor gemacht werden und sieht dann wie folgt aus:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"json\" class=\"language-json\">        \"panelsJSON\": \"[{\\\"type\\\":\\\"visualization\\\",\n------&gt;\\\"gridData\\\":{\\\"x\\\":0,\n------&gt;\\\"y\\\":0,\n------&gt;\\\"w\\\":20,\n------&gt;\\\"h\\\":9,\n------&gt;\\\"i\\\":\\\"09747f18-d4b6-4cb0-a25e-63abf3a9cce8\\\"},\n------&gt;\\\"panelIndex\\\":\\\"09747f18-d4b6-4cb0-a25e-63abf3a9cce8\\\",\n------&gt;\\\"embeddableConfig\\\":{\\\"enhancements\\\":{\\\"dynamicActions\\\":{\\\"events\\\":[]}},\n------&gt;\\\"savedVis\\\":{\\\"id\\\":\\\"\\\",\n------&gt;\\\"title\\\":\\\"\\\",\n------&gt;\\\"description\\\":\\\"\\\",\n------&gt;\\\"type\\\":\\\"markdown\\\",\n------&gt;\\\"params\\\":{\\\"fontSize\\\":12,\n------&gt;\\\"openLinksInNewTab\\\":false,\n------&gt;\\\"markdown\\\":\\\"# Markdown_Titel\\\\n\\\\nTextzeile1\\\\n\\\\nTextzeile 2\\\\n\\\\n\ud83d\ude03\\\"},\n------&gt;\\\"uiState\\\":{},\n------&gt;\\\"data\\\":{\\\"aggs\\\":[],\n------&gt;\\\"searchSource\\\":{\\\"query\\\":{\\\"query\\\":\\\"\\\",\n------&gt;\\\"language\\\":\\\"kuery\\\"},\n------&gt;\\\"filter\\\":[]}}}}},\n------&gt;{\\\"type\\\":\\\"visualization\\\",\n------&gt;\\\"gridData\\\":{\\\"x\\\":0,\n------&gt;\\\"y\\\":0,\n------&gt;\\\"w\\\":20,\n------&gt;\\\"h\\\":9,\n------&gt;\\\"i\\\":\\\"09747f18-d4b6-4cb0-a25e-63abf3a9cce8\\\"},\n------&gt;\\\"panelIndex\\\":\\\"09747f18-d4b6-4cb0-a25e-63abf3a9cce8\\\",\n------&gt;\\\"embeddableConfig\\\":{\\\"enhancements\\\":{\\\"dynamicActions\\\":{\\\"events\\\":[]}},\n------&gt;\\\"savedVis\\\":{\\\"id\\\":\\\"\\\",\n------&gt;\\\"title\\\":\\\"\\\",\n------&gt;\\\"description\\\":\\\"\\\",\n------&gt;\\\"type\\\":\\\"markdown\\\",\n------&gt;\\\"params\\\":{\\\"fontSize\\\":12,\n------&gt;\\\"openLinksInNewTab\\\":false,\n------&gt;\\\"markdown\\\":\\\"# Markdown_Titel\\\\n\\\\nTextzeile1\\\\n\\\\nTextzeile 2\\\\n\\\\n\ud83d\ude03\\\"},\n------&gt;\\\"uiState\\\":{},\n------&gt;\\\"data\\\":{\\\"aggs\\\":[],\n------&gt;\\\"searchSource\\\":{\\\"query\\\":{\\\"query\\\":\\\"\\\",\n------&gt;\\\"language\\\":\\\"kuery\\\"},\n------&gt;\\\"filter\\\":[]}}}}},\n------&gt;{\\\"type\\\":\\\"visualization\\\",\n------&gt;\\\"gridData\\\":{\\\"x\\\":0,\n\u2026 \u2026\n------&gt;\\\"language\\\":\\\"kuery\\\"},\n------&gt;\\\"filter\\\":[]}}}}}]\",\n        \"timeRestore\": false,\n        \"title\": \"Blog_Beispiel2\",\n        \"version\": 2\n    },\n    \"coreMigrationVersion\": \"8.8.0\",<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">L\u00f6schen der Panel-Indices<\/h3>\n\n\n\n<p>Ein Panel bekommt in Kibana einen Index-Wert. Diese m\u00fcssen (ausser dem ersten) gel\u00f6scht werden, resp. es darf nicht mehrmals derselbe Index vorkommen, sonst \u00fcberschreiben sich die Panels. Folgende Zeilen in der Datei <em>blog_beispiel2.j2<\/em> m\u00fcssen also noch gel\u00f6scht werden:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"json\" class=\"language-json\">-----\u2192\\\"panelIndex\\\":\\\"09747f18-d4b6-4cb0-a25e-63abf3a9cce8\\\",<\/code><\/pre>\n\n\n\n<p>Auch die Dashboard-Id sollte am besten wieder gel\u00f6scht werden.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Einf\u00fcgen von jinja2 Elementen<\/h3>\n\n\n\n<p>Analog Beispiel 1 k\u00f6nnen nun die Variablen aus der Inputdatei eingef\u00fcgt werden. Man hat dabei eine Array-Ebene mehr als im ersten Beispiel und neben den Texten sind auch noch die Positionen und die Gr\u00f6sse der Panels anzugeben. Auszugsweise sieht das dann so aus:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"json\" class=\"language-json\">        \"panelsJSON\": \"[{\\\"type\\\":\\\"visualization\\\",\n------&gt;\\\"gridData\\\":{\\\"x\\\":{{ markdown.0.position.0 }},\n------&gt;\\\"y\\\":{{ markdown.0.position.1 }},\n------&gt;\\\"w\\\":{{ markdown.0.groesse.0 }},\n------&gt;\\\"h\\\":{{ markdown.0.groesse.1 }},\n\u2026 \u2026\n------&gt;\\\"markdown\\\":\\\"# {{ markdown.0.title }}\\\\n\\\\n{{ markdown.0.textzeilen.0 }}\\\\n\\\\n{{ markdown.0.textzeilen.1 }}\\\\n\\\\n{{ markdown.0.textzeilen.2 }}\\\"},\n\u2026 \u2026<\/code><\/pre>\n\n\n\n<p>F\u00fcr die weiteren zwei Panels heisst es dann <code>{{ markdown.1. \u2026 }}<\/code> und <code>{{ markdown.2. \u2026 }}<\/code>.<\/p>\n\n\n\n<p>Auch der Name des Dashboards muss noch angepasst werden:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"json\" class=\"language-json\">\"title\":\"{{ dashboard_title }}\"<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">Weitere Schritte<\/h3>\n\n\n\n<p>Analog Beispiel 1 muss die Datei <em>blog_beispiel2.j2<\/em> wieder als ndjson formatiert werden.<\/p>\n\n\n\n<p>Dann kann das Dashboard generiert werden mit dem Befehl:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"bash\" class=\"language-bash\">jinjanate blog_beispiel2.j2 blog_beispiel2_vars.json -o generiertes_dashboard_blog_beispiel2.ndjson<\/code><\/pre>\n\n\n\n<p>Das generierte Dashboard wird wiederum mit der Option \u00abCreate new objects with random Ids\u00bb importiert. Das Resultat sieht man im folgenden Screenshot:<\/p>\n\n\n<style>.kb-image7908_7310ae-75 .kb-image-has-overlay:after{opacity:0.3;}<\/style>\n<figure class=\"wp-block-kadence-image kb-image7908_7310ae-75 size-medium_large\"><img loading=\"lazy\" decoding=\"async\" width=\"768\" height=\"614\" src=\"https:\/\/swissmakers.ch\/wp-content\/uploads\/2025\/03\/Blog-Kibana-2-768x614.png\" alt=\"\" class=\"kb-img wp-image-7913\" srcset=\"https:\/\/swissmakers.ch\/wp-content\/uploads\/2025\/03\/Blog-Kibana-2-768x614.png 768w, https:\/\/swissmakers.ch\/wp-content\/uploads\/2025\/03\/Blog-Kibana-2-300x240.png 300w, https:\/\/swissmakers.ch\/wp-content\/uploads\/2025\/03\/Blog-Kibana-2-1024x819.png 1024w, https:\/\/swissmakers.ch\/wp-content\/uploads\/2025\/03\/Blog-Kibana-2-15x12.png 15w, https:\/\/swissmakers.ch\/wp-content\/uploads\/2025\/03\/Blog-Kibana-2.png 1200w\" sizes=\"auto, (max-width: 768px) 100vw, 768px\" \/><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\">Generieren von mehreren Panels in einer Schleife<\/h2>\n\n\n\n<p>Das Dashboard aus Beispiel 2 l\u00e4sst sich auch etwas eleganter generieren. Anstelle der Aneinanderreihung der Markdown-Panels im jinja2-Template k\u00f6nnen die Panels in Beispiel 3 in einer Schleife generiert werden. Diese L\u00f6sung bietet mehr Flexibilit\u00e4t.<\/p>\n\n\n\n<p>Als Inputdatei mit Variablen wird vorerst eine Kopie <em>blog_beispiel3_vars.json<\/em> der Inputdatei von Beispiel 2 gebraucht, in der nur der Name resp. Titel des Dashboards auf <em>generiertes_dashboard_blog_beispiel3<\/em> angepasst worden ist.<\/p>\n\n\n\n<p><em>blog_beispiel3.json<\/em> ist wieder die umformatierte Datei mit dem urspr\u00fcnglich interaktiv erstellten Dashboard, in die nun jinja2-Elemente eingef\u00fcgt werden. Die Datei ist vorerst eine Kopie von <em>blog_beispiel1.json<\/em>, die nur die Definition eines Markdown-Panels enth\u00e4lt, nicht die Datei mit den drei Panels aus Beispiel 2. Hier nun der entsprechende Teil der Datei mit den neuen jinja2-Elementen:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"json\" class=\"language-json\">        \"panelsJSON\": \"[{% for item in markdown %}{\\\"type\\\":\\\"visualization\\\",\n-------&gt;\\\"gridData\\\":{\\\"x\\\":{{ markdown[loop.index0]['position'][0] }},\n-------&gt;\\\"y\\\":{{ markdown[loop.index0]['position'][1] }},\n-------&gt;\\\"w\\\":{{ markdown[loop.index0]['groesse'][0] }},\n-------&gt;\\\"h\\\":{{ markdown[loop.index0]['groesse'][1] }},\n-------&gt;\\\"i\\\":\\\"09747f18-d4b6-4cb0-a25e-63abf3a9cce8\\\"},\n-------&gt;\\\"embeddableConfig\\\":{\\\"enhancements\\\":{\\\"dynamicActions\\\":{\\\"events\\\":[]}},\n-------&gt;\\\"savedVis\\\":{\\\"id\\\":\\\"\\\",\n-------&gt;\\\"title\\\":\\\"\\\",\n-------&gt;\\\"description\\\":\\\"\\\",\n-------&gt;\\\"type\\\":\\\"markdown\\\",\n-------&gt;\\\"params\\\":{\\\"fontSize\\\":12,\n-------&gt;\\\"openLinksInNewTab\\\":false,\n-------&gt;\\\"markdown\\\":\\\"# {{ markdown[loop.index0]['title'] }}\\\\n\\\\n{{ markdown[loop.index0]['textzeilen'][0] }}\\\\n\\\\n{{ markdown[loop.index0]['textzeilen'][1] }}\\\\n\\\\n{{ markdown[loop.index0]['textzeilen'][2] }}\\\"},\n-------&gt;\\\"uiState\\\":{},\n-------&gt;\\\"data\\\":{\\\"aggs\\\":[],\n-------&gt;\\\"searchSource\\\":{\\\"query\\\":{\\\"query\\\":\\\"\\\",\n-------&gt;\\\"language\\\":\\\"kuery\\\"},\n-------&gt;\\\"filter\\\":[]}}}}}{% if loop.index != loop.length %},{% endif %}\n{% endfor %}]\",\n        \"timeRestore\": false,\n        \"title\": \"{{ dashboard_title }}\",\n        \"version\": 2\n    },<\/code><\/pre>\n\n\n\n<p>In jinja2 kann eine Schleife mit den folgenden Elementen definiert werden:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"json\" class=\"language-json\"><code>{% for item in markdown %}<\/code>\n<code>{% endfor %}<\/code><\/code><\/pre>\n\n\n\n<p>F\u00fcr jedes Element im Array <em>markdown<\/em> in der Inputdatei wird dann der ganze Teil innerhalb der Schleife wiederholt. Damit erh\u00e4lt man die drei Paneldefinitionen im Output.<\/p>\n\n\n\n<p>Wie beim Anpassen der Datei f\u00fcr Beispiel 2 muss man beachten, dass die Paneldefinitionen in einem json-Array stehen, zwischen dessen Elementen ein Komma stehen muss, aber am Ende des Arrays darf kein Komma mehr stehen. Dies kann mit einer Bedingung in jinja2 erreicht werden:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"json\" class=\"language-json\">{% if loop.index != loop.length %},{% endif %}<\/code><\/pre>\n\n\n\n<p>Wenn der Schleifenindex noch nicht gleich der Anzahl Schleifen ist, so wird das Komma zwischen der if-Bedingung und dem <code>{% endif %}<\/code> in den Output geschrieben, aber beim letzten Schleifendurchgang nicht mehr.<\/p>\n\n\n\n<p>F\u00fcr die Angabe der Arrayelemente aus der Inputdatei wird hier eine alternative Syntax verwendet, bei der die Array-Ebenen nicht durch Punkte getrennt sind wie es in Beispiel 1 und Beispiel 2 gebraucht wurde, sondern in eckigen Klammern angegeben werden. <code>loop.index0<\/code> ist eine Variable, die innerhalb einer for-Schleife zur Verf\u00fcgung steht und die angibt, in welchem Durchgang der Schleife man ist, wenn mit 0 zu z\u00e4hlen begonnen wird, um Unterschied zur oben verwendeten Variable <code>loop.index<\/code>, bei der mit 1 zu z\u00e4hlen begonnen wird. Die Namensteile ohne Anf\u00fchrungs- und Schlusszeichen sind jinja2-Variablen, deren Wert dort eingesetzt wird, jene in Anf\u00fchrungs- und Schlusszeichen sind die Namen aus dem json in der Inputdatei. Anf\u00fchrungs- und Schlusszeichen sind also wichtig und m\u00fcssen korrekt gesetzt sein.<\/p>\n\n\n\n<p>Wie in den anderen Beispielen muss nun die Datei umformatiert und als ganzes Template <em>blog_beispiel3.j2<\/em> gespeichert werden.<\/p>\n\n\n\n<p>Der Befehl<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"bash\" class=\"language-bash\">jinjanate blog_beispiel3.j2 blog_beispiel3_vars.json -o generiertes_dashboard_blog_beispiel3.ndjson<\/code><\/pre>\n\n\n\n<p>generiert dann ein Dashboard, das genau so aussieht wie jenes in Beispiel 2.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Neue Inputdatei mit Variablen<\/h3>\n\n\n\n<p>Mit der Schleife im Template ist Beispiel 3 nun viel flexibler als Beispiel 2. Es gen\u00fcgt, die Inputdatei anzupassen, um unterschiedlich viele Markdown-Panels im Dashboard zu generieren. Es k\u00f6nnen nat\u00fcrlich auch verschiedene Inputdateien mit demselben Template verwendet werden, z.B. f\u00fcr verschiedene Stages (dev, preprod, prod) etc.<\/p>\n\n\n\n<p>Hier eine neue Inputdatei:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"json\" class=\"language-json\">{\n    \"markdown\": [\n        {\n            \"title\": \"**Swissmakers**\",\n            \"textzeilen\": [\n                \"Aus Freude an Technik\",\n                \"Engeneering \/ Security \/ Consulting\",\n                \"swissmakers.ch \ud83d\ude0a\"\n            ],\n            \"position\": [0,0],\n            \"groesse\": [15,8]\n        },\n        {\n            \"title\": \"**Swissmakers**\",\n            \"textzeilen\": [\n                \"Einfach Top!\",\n                \"swissmakers.ch \ud83d\ude0a \ud83d\udc4d \ud83d\udcaa \ud83d\udc4d \ud83d\ude04\",\n                \"\"\n            ],\n            \"position\": [18,0],\n            \"groesse\": [15,8]\n        },\n        {\n            \"title\": \"**Codeatelier**\",\n            \"textzeilen\": [\n                \"Wir bauen deine digitale Zukunft\",\n                \"Webdesign \ud83d\udfe2 SEO \ud83d\udfe2 Webapps \ud83d\udfe2 Webshops\",\n                \"codeatelier.ch \ud83d\ude03\"\n            ],\n            \"position\": [9,9],\n            \"groesse\": [18,8]\n        },\n        {\n            \"title\": \"**Swissmakers**\",\n            \"textzeilen\": [\n                \"Ihre ITC-Spezialistinnen und -Spezialisten\",\n                \"Engeneering, Linux und Netzsicherheit\",\n                \"swissmakers.ch \ud83d\udc4d\"\n            ],\n            \"position\": [0,18],\n            \"groesse\": [18,8]\n        },\n        {\n            \"title\": \"**Swissmakers**\",\n            \"textzeilen\": [\n                \"Ihre ITC-Expertinnen und -Experten\",\n                \"f\u00fcr ihre Private Cloud basierend auf Nextcloud\",\n                \"swissmakers.ch \ud83d\udc4d\"\n            ],\n            \"position\": [18,18],\n            \"groesse\": [18,8]\n        }\n    ],\n    \"dashboard_title\": \"generiertes_dashboard_blog_beispiel3_b\"\n}<\/code><\/pre>\n\n\n\n<p>Ohne weitere Anpassungen wird daraus mit demselben Template das folgende Dashboard generiert:<\/p>\n\n\n<style>.kb-image7908_fe711c-f3 .kb-image-has-overlay:after{opacity:0.3;}<\/style>\n<figure class=\"wp-block-kadence-image kb-image7908_fe711c-f3 size-medium_large\"><img loading=\"lazy\" decoding=\"async\" width=\"768\" height=\"488\" src=\"https:\/\/swissmakers.ch\/wp-content\/uploads\/2025\/03\/Blog-Kibana-3-768x488.png\" alt=\"\" class=\"kb-img wp-image-7914\" srcset=\"https:\/\/swissmakers.ch\/wp-content\/uploads\/2025\/03\/Blog-Kibana-3-768x488.png 768w, https:\/\/swissmakers.ch\/wp-content\/uploads\/2025\/03\/Blog-Kibana-3-300x190.png 300w, https:\/\/swissmakers.ch\/wp-content\/uploads\/2025\/03\/Blog-Kibana-3-1024x650.png 1024w, https:\/\/swissmakers.ch\/wp-content\/uploads\/2025\/03\/Blog-Kibana-3-18x12.png 18w, https:\/\/swissmakers.ch\/wp-content\/uploads\/2025\/03\/Blog-Kibana-3.png 1380w\" sizes=\"auto, (max-width: 768px) 100vw, 768px\" \/><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\">Automatisches Anordnen von Panels<\/h2>\n\n\n\n<p>In Beispiel 4 geht es darum, ein paar weitere M\u00f6glichkeiten von jinja2-Templates zu zeigen und Panels im Dashboard automatisch in Zeilen und Spalten anzuordnen.<\/p>\n\n\n\n<p>Es wird eine feste Anzahl von Markdown-Panels verwendet, die je nach der gew\u00fcnschten Anzahl Panels im Dashboard wiederholt werden.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Inputdatei mit Variablen<\/h3>\n\n\n\n<p>Als Inputdatei mit Variablen wird eine Kopie der Inputdatei von Beispiel 3 verwendet. Gr\u00f6sse und Position der Markdown-Panels werden aber f\u00fcr alle Panels einheitlich gesetzt und ausserhalb des markdown-Arrays im json-File definiert. Dort wird auch die gew\u00fcnschte Anzahl Markdown-Panels und die Anzahl Spalten f\u00fcr die Panels im Dashboard angegeben. Die Breite der Panels ist kleiner definiert als in den vorangehenden Beispielen, weil die Panels sonst in Kibana automatisch etwas anders angeordnet werden, da sie nicht wie eigentlich gew\u00fcnscht Platz finden im Dashboard.<\/p>\n\n\n\n<p>Die Inputdatei <em>blog_beispiel4_vars.json<\/em> sieht wie folgt aus:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"json\" class=\"language-json\">{\n    \"hoehe\": 8,\n    \"breite\": 10,\n    \"spalten\": 4,\n    \"anzahl\": 20,\n    \"markdown\": [\n        {\n            \"title\": \"**Swissmakers**\",\n            \"textzeilen\": [\n                \"Aus Freude an Technik\",\n                \"Engeneering \/ Security \/ Consulting\",\n                \"swissmakers.ch \ud83d\ude0a\"\n            ]\n        },\n        {\n            \"title\": \"**Swissmakers**\",\n            \"textzeilen\": [\n                \"Einfach Top!\",\n                \"swissmakers.ch \ud83d\ude0a \ud83d\udc4d \ud83d\udcaa \ud83d\udc4d \ud83d\ude04\",\n                \"\"\n            ]\n        },\n        {\n            \"title\": \"**Codeatelier**\",\n            \"textzeilen\": [\n                \"Wir bauen deine digitale Zukunft\",\n                \"Webdesign \ud83d\udfe2 SEO \ud83d\udfe2 Webapps \ud83d\udfe2 Webshops\",\n                \"codeatelier.ch \ud83d\ude03\"\n            ]\n        },\n        {\n            \"title\": \"**Swissmakers**\",\n            \"textzeilen\": [\n                \"Ihre ITC-Spezialistinnen und -Spezialisten\",\n                \"Engeneering, Linux und Netzsicherheit\",\n                \"swissmakers.ch \ud83d\udc4d\"\n            ]\n        },\n        {\n            \"title\": \"**Swissmakers**\",\n            \"textzeilen\": [\n                \"Ihre ITC-Expertinnen und -Experten\",\n                \"f\u00fcr ihre Private Cloud basierend auf Nextcloud\",\n                \"swissmakers.ch \ud83d\udc4d\"\n            ]\n        }\n    ],\n    \"dashboard_title\": \"generiertes_dashboard_blog_beispiel4\"\n}<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">Generieren und anordnen der Panels<\/h2>\n\n\n\n<p><em>blog_beispiel4.json<\/em> ist wieder die umformatierte Datei mit dem urspr\u00fcnglich interaktiv erstellten Dashboard.<\/p>\n\n\n\n<p>F\u00fcr das Beispiel 4 ist noch der Panel-Titel ausgeschaltet und die Schriftgr\u00f6sse etwas verkleinert worden.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"json\" class=\"language-json\">        \"optionsJSON\": \"{\\\"useMargins\\\":true,\\\"syncColors\\\":false,\\\"syncCursor\\\":true,\\\"syncTooltips\\\":false,\\\"hidePanelTitles\\\":true}\",\n\n------\u2192\\\"params\\\":{\\\"fontSize\\\":10,<\/code><\/pre>\n\n\n\n<p>In <em>blog_beispiel4.json<\/em> werden nun wiederum jinja2-Elemente eingef\u00fcgt. Hier nun der entsprechende Teil der Datei mit den teilweise neuen jinja2-Elementen:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"json\" class=\"language-json\">        \"panelsJSON\": \"{% set global = namespace(row = 0) %}[{% for i in range(0, anzahl - 1) %}{\\\"type\\\":\\\"visualization\\\",\n-------&gt;\\\"gridData\\\":{\\\"x\\\":{{ (i) % spalten * breite }},\n-------&gt;\\\"y\\\":{{ hoehe * global.row }}{% if (i + 1) % spalten == 0 %}{% set global.row = global.row + 1 %}{% endif %},\n-------&gt;\\\"w\\\":{{ breite }},\n-------&gt;\\\"h\\\":{{ hoehe }},\n-------&gt;\\\"i\\\":\\\"09747f18-d4b6-4cb0-a25e-63abf3a9cce8\\\"},\n-------&gt;\\\"embeddableConfig\\\":{\\\"enhancements\\\":{\\\"dynamicActions\\\":{\\\"events\\\":[]}},\n-------&gt;\\\"savedVis\\\":{\\\"id\\\":\\\"\\\",\n-------&gt;\\\"title\\\":\\\"\\\",\n-------&gt;\\\"description\\\":\\\"\\\",\n-------&gt;\\\"type\\\":\\\"markdown\\\",\n-------&gt;\\\"params\\\":{\\\"fontSize\\\":10,\n-------&gt;\\\"openLinksInNewTab\\\":false,\n-------&gt;\\\"markdown\\\":\\\"# {{ markdown[i % markdown|length]['title'] }}\\\\n\\\\n{{ markdown[i % markdown|length]['textzeilen'][0] }}\\\\n\\\\n{{ markdown[i % markdown|length]['textzeilen'][1] }}\\\\n\\\\n{{ markdown[i % markdown|length]['textzeilen'][2] }}\\\"},\n-------&gt;\\\"uiState\\\":{},\n-------&gt;\\\"data\\\":{\\\"aggs\\\":[],\n-------&gt;\\\"searchSource\\\":{\\\"query\\\":{\\\"query\\\":\\\"\\\",\n-------&gt;\\\"language\\\":\\\"kuery\\\"},\n-------&gt;\\\"filter\\\":[]}}}}}{% if loop.index != loop.length %},{% endif %}{% endfor %}]\",<\/code><\/pre>\n\n\n\n<p>Die insgesamt 20 Markdown-Panels <code>\u00abanzahl\u00bb: 20<\/code> sollen in Zeilen mit je 4 Panels <code>\u00abspalten\u00bb: 4<\/code> angeordnet werden. Dazu wird die Hilfsvariable <code>row<\/code> definiert, in der die Zeile f\u00fcr das Panel steht und mit der dann die y-Position berechnet wird. <code>row<\/code> wird mit dem Wert 0 initialisiert:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"json\" class=\"language-json\">{% set global = namespace(row = 0) %}<\/code><\/pre>\n\n\n\n<p>Die Schleife \u00fcber die Panels wird etwas anders definiert als zuvor:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"json\" class=\"language-json\">{% for i in range(0, anzahl) %}<\/code><\/pre>\n\n\n\n<p>Man hat so die Schleifenvariable i, die von 0 bis <code>anzahl<\/code> -1, im Beispiel also von 0 bis 29, l\u00e4uft. Die obere Grenze <code>anzahl<\/code> in der range-Funktion wird von der Funktion nicht zur\u00fcck geliefert, man muss also <code>anzahl<\/code> und nicht <code>anzahl<\/code> \u2013 1 als obere Grenze angeben. Am Ende der Schleife hat man wieder die Bedingung wegen den Kommata zwischen den Paneldefinitionen aber nicht am Ende das Arrays:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"json\" class=\"language-json\">{% if loop.index != loop.length %},{% endif %}<\/code><\/pre>\n\n\n\n<p><code>%<\/code> ist in Jinja2 der Modulo-Operator, der den Rest einer ganzzahligen Division angibt. Damit lassen sich die jeweiligen x-Positionen der Panels berechnen:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"json\" class=\"language-json\">{{ (i) % spalten * breite }}<\/code><\/pre>\n\n\n\n<p>Beim Zugriff auf die Elemente des markdown-Arrays in der Inputdatei wird ebenfalls der Modulo-Operator zusammen mit der Laufvariable <code>i<\/code> verwendet, um nach dem letzten Array-Element wieder auf das erste zuzugreifen:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"json\" class=\"language-json\">{{ markdown[i % markdown|length]['title'] }}<\/code><\/pre>\n\n\n\n<p>Mit dem Filter <code>length<\/code> in <code>markdown|length<\/code> erh\u00e4lt man die Anzahl Elemente im Array <code>markdown<\/code>, die man hier braucht.<\/p>\n\n\n\n<p>Wie in den anderen Beispielen muss nun die Datei umformatiert und als ganzes Template <em>blog_beispiel4.j2<\/em> gespeichert werden.<\/p>\n\n\n\n<p>Der Befehl<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"bash\" class=\"language-bash\">jinjanate blog_beispiel4.j2 blog_beispiel4_vars.json -o generiertes_dashboard_blog_beispiel4.ndjson<\/code><\/pre>\n\n\n\n<p>generiert nun folgendes Dashboard, in dem die Markdown-Panels wiederholt werden und regelm\u00e4ssig in 4 Spalten angeordnet sind:<\/p>\n\n\n<style>.kb-image7908_6edd81-a5 .kb-image-has-overlay:after{opacity:0.3;}<\/style>\n<figure class=\"wp-block-kadence-image kb-image7908_6edd81-a5 size-medium_large\"><img loading=\"lazy\" decoding=\"async\" width=\"768\" height=\"641\" src=\"https:\/\/swissmakers.ch\/wp-content\/uploads\/2025\/03\/Blog-Kibana-4-768x641.png\" alt=\"\" class=\"kb-img wp-image-7915\" srcset=\"https:\/\/swissmakers.ch\/wp-content\/uploads\/2025\/03\/Blog-Kibana-4-768x641.png 768w, https:\/\/swissmakers.ch\/wp-content\/uploads\/2025\/03\/Blog-Kibana-4-300x250.png 300w, https:\/\/swissmakers.ch\/wp-content\/uploads\/2025\/03\/Blog-Kibana-4-1024x854.png 1024w, https:\/\/swissmakers.ch\/wp-content\/uploads\/2025\/03\/Blog-Kibana-4-1536x1282.png 1536w, https:\/\/swissmakers.ch\/wp-content\/uploads\/2025\/03\/Blog-Kibana-4-14x12.png 14w, https:\/\/swissmakers.ch\/wp-content\/uploads\/2025\/03\/Blog-Kibana-4.png 1546w\" sizes=\"auto, (max-width: 768px) 100vw, 768px\" \/><\/figure>\n\n\n\n<h2 class=\"gb-headline gb-headline-09e2fd62 gb-headline-text\">Dashboards mit Elastic-Daten<\/h2>\n\n\n\n<p class=\"gb-headline gb-headline-e6ab0f43 gb-headline-text\">Sie kennen nun erste Beispiele. Erkunden Sie die M\u00f6glichkeit der Dashboard-Generierung mit Elastic-Beispieldaten in einigen Wochen in unserem n\u00e4chsten Teil dieses Blogbeitrags.<\/p>\n\n\n\n<p class=\"gb-headline gb-headline-e2c548f9 gb-headline-text\">Nat\u00fcrlich k\u00f6nnen Sie jederzeit auf Swissmakers zukommen f\u00fcr Unterst\u00fctzung bei der Erstellung professioneller Kibana-Dashboards.<\/p>\n\n\n\n<p><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Simple Markdown panel This first example is just to show the procedure. Dashboard ... <\/p>\n<p class=\"read-more-container\"><a title=\"Generate Kibana dashboards flexibly - Part 2\/3\" class=\"read-more button\" href=\"https:\/\/swissmakers.ch\/en\/flexibel-kibana-dashboards-generieren-teil-2-3\/#more-7908\" aria-label=\"Read more about Generate Kibana dashboards flexibly - Part 2\/3\">Read more<\/a><\/p>","protected":false},"author":9,"featured_media":7868,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_eb_attr":"","_kad_blocks_custom_css":"","_kad_blocks_head_custom_js":"","_kad_blocks_body_custom_js":"","_kad_blocks_footer_custom_js":"","footnotes":""},"categories":[55,69,70,71,16],"tags":[],"class_list":["post-7908","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-linux","category-automatisierung","category-elastic","category-kibana","category-monitoring","generate-columns","tablet-grid-50","mobile-grid-100","grid-parent","grid-50"],"taxonomy_info":{"category":[{"value":55,"label":"Linux"},{"value":69,"label":"Automatisierung"},{"value":70,"label":"Elastic"},{"value":71,"label":"Kibana"},{"value":16,"label":"Monitoring"}]},"featured_image_src_large":["https:\/\/swissmakers.ch\/wp-content\/uploads\/2025\/02\/Bild-Kibana-Dashboards-1200x600-1-1024x512.png",1024,512,true],"author_info":{"display_name":"Matthias Dillier","author_link":"https:\/\/swissmakers.ch\/en\/author\/matthias\/"},"comment_info":0,"category_info":[{"term_id":55,"name":"Linux","slug":"linux","term_group":0,"term_taxonomy_id":55,"taxonomy":"category","description":"","parent":0,"count":10,"filter":"raw","cat_ID":55,"category_count":10,"category_description":"","cat_name":"Linux","category_nicename":"linux","category_parent":0},{"term_id":69,"name":"Automatisierung","slug":"automatisierung","term_group":0,"term_taxonomy_id":69,"taxonomy":"category","description":"","parent":0,"count":3,"filter":"raw","cat_ID":69,"category_count":3,"category_description":"","cat_name":"Automatisierung","category_nicename":"automatisierung","category_parent":0},{"term_id":70,"name":"Elastic","slug":"elastic","term_group":0,"term_taxonomy_id":70,"taxonomy":"category","description":"","parent":16,"count":3,"filter":"raw","cat_ID":70,"category_count":3,"category_description":"","cat_name":"Elastic","category_nicename":"elastic","category_parent":16},{"term_id":71,"name":"Kibana","slug":"kibana","term_group":0,"term_taxonomy_id":71,"taxonomy":"category","description":"","parent":16,"count":3,"filter":"raw","cat_ID":71,"category_count":3,"category_description":"","cat_name":"Kibana","category_nicename":"kibana","category_parent":16},{"term_id":16,"name":"Monitoring","slug":"monitoring","term_group":0,"term_taxonomy_id":16,"taxonomy":"category","description":"","parent":0,"count":8,"filter":"raw","cat_ID":16,"category_count":8,"category_description":"","cat_name":"Monitoring","category_nicename":"monitoring","category_parent":0}],"tag_info":false,"_links":{"self":[{"href":"https:\/\/swissmakers.ch\/en\/wp-json\/wp\/v2\/posts\/7908","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/swissmakers.ch\/en\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/swissmakers.ch\/en\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/swissmakers.ch\/en\/wp-json\/wp\/v2\/users\/9"}],"replies":[{"embeddable":true,"href":"https:\/\/swissmakers.ch\/en\/wp-json\/wp\/v2\/comments?post=7908"}],"version-history":[{"count":15,"href":"https:\/\/swissmakers.ch\/en\/wp-json\/wp\/v2\/posts\/7908\/revisions"}],"predecessor-version":[{"id":8007,"href":"https:\/\/swissmakers.ch\/en\/wp-json\/wp\/v2\/posts\/7908\/revisions\/8007"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/swissmakers.ch\/en\/wp-json\/wp\/v2\/media\/7868"}],"wp:attachment":[{"href":"https:\/\/swissmakers.ch\/en\/wp-json\/wp\/v2\/media?parent=7908"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/swissmakers.ch\/en\/wp-json\/wp\/v2\/categories?post=7908"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/swissmakers.ch\/en\/wp-json\/wp\/v2\/tags?post=7908"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}