{"id":52343,"date":"2019-11-06T00:00:00","date_gmt":"2019-11-05T21:00:00","guid":{"rendered":"https:\/\/prohoster.info\/blog\/blog_prohoster\/razrabotka-plagina-dlya-grafana-istoriya-nabityh-shishek"},"modified":"2020-02-18T14:00:02","modified_gmt":"2020-02-18T11:00:02","slug":"razrabotka-plagina-dlya-grafana-istoriya-nabityh-shishek","status":"publish","type":"post","link":"https:\/\/prohoster.info\/sv\/blog\/administrirovanie\/razrabotka-plagina-dlya-grafana-istoriya-nabityh-shishek","title":{"rendered":"Utveckling av plugin f\u00f6r Grafana: en historia av samlade erfarenheter","gt_translate_keys":[{"key":"rendered","format":"text"}]},"content":{"rendered":"<p>Hej alla! F\u00f6r n\u00e5gra m\u00e5nader sedan lanserade vi v\u00e5rt nya open-source projekt i produktion \u2014 en Grafana-plugin f\u00f6r \u00f6vervakning av Kubernetes, som vi har d\u00f6pt till <b><noindex><a rel=\"nofollow\" href=\"https:\/\/grafana.com\/grafana\/plugins\/devopsprodigy-kubegraf-app\">DevOpsProdigy KubeGraf<\/a><\/noindex><\/b>. K\u00e4llkoden f\u00f6r pluginet finns tillg\u00e4nglig i <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/devopsprodigy\/kubegraf\">ett offentligt arkiv p\u00e5 GitHub<\/a><\/noindex>. I den h\u00e4r artikeln vill vi dela med er historien om hur vi skapade pluginet, vilka verktyg vi anv\u00e4nde och vilka hinder vi st\u00f6tte p\u00e5 under utvecklingen. L\u00e5t oss b\u00f6rja!<br \/>\n<noindex><a rel=\"nofollow\" name=\"habracut\"><\/a><\/noindex><\/p>\n<h4>Del 0 \u2014 introduktion: hur kom vi dit?<\/h4>\n<p>\nId\u00e9n att skriva v\u00e5r egen plugin f\u00f6r Grafana f\u00f6ddes av en slump. V\u00e5rt f\u00f6retag har arbetat med \u00f6vervakning av webbprojekt i olika komplexitetsniv\u00e5er i \u00f6ver 10 \u00e5r. Under denna tid har vi samlat p\u00e5 oss mycket expertis, intressanta fallstudier och erfarenheter av att anv\u00e4nda olika \u00f6vervakningssystem. Vid n\u00e5got tillf\u00e4lle st\u00e4llde vi oss fr\u00e5gan: \"Finns det ett magiskt verktyg f\u00f6r att \u00f6vervaka Kubernetes, s\u00e5 att man kan 'installera och gl\u00f6mma'\"?.. Standardl\u00f6sningen f\u00f6r att \u00f6vervaka k8s \u00e4r naturligtvis sedan l\u00e4nge en kombination av Prometheus + Grafana. Och det finns en m\u00e4ngd olika verktyg som erbjuder f\u00e4rdiga l\u00f6sningar f\u00f6r denna teknikstack: prometheus-operator, en upps\u00e4ttning dashboards fr\u00e5n kubernetes-mixin, grafana-kubernetes-app. <\/p>\n<p>Det mest intressanta alternativet f\u00f6r oss verkade vara pluginet grafana-kubernetes-app, men det har inte underh\u00e5llits p\u00e5 \u00f6ver ett \u00e5r och dessutom fungerar det inte med de nya versionerna av node-exporter och kube-state-metrics. Vid n\u00e5got tillf\u00e4lle beslutade vi: \"Varf\u00f6r inte g\u00f6ra v\u00e5r egen l\u00f6sning?\"<\/p>\n<p>Vilka id\u00e9er beslutade vi oss f\u00f6r att genomf\u00f6ra i v\u00e5rt plugin:<\/p>\n<ul>\n<li>visualisering av \"applikationskartan\": en anv\u00e4ndarv\u00e4nlig representation av applikationer i klustret, grupperade efter namespaces, deployments\u2026;<\/li>\n<li>visualisering av relationer som \"deployment \u2014 service (+ports)\".<\/li>\n<li>visualisering av distributionen av klustrets applikationer \u00f6ver noderna i klustret.<\/li>\n<li>insamling av metrik och information fr\u00e5n flera k\u00e4llor: Prometheus och k8s API-server.<\/li>\n<li>\u00f6vervakning av b\u00e5de infrastrukturdelarna (anv\u00e4ndning av processor, minne, lagringssystem, n\u00e4tverk) och applikationernas logik \u2014 h\u00e4lsostatus f\u00f6r pods, antal tillg\u00e4ngliga repliker, information om genomf\u00f6rande av liveness\/readiness-checkar.<\/li>\n<\/ul>\n<p><\/p>\n<h4>Del 1: Vad \u00e4r en \"plugin f\u00f6r Grafana\"?<\/h4>\n<p>\nUr ett tekniskt perspektiv \u00e4r en plugin f\u00f6r Grafana en Angular-kontroller som lagras i data-katalogen f\u00f6r Grafana (<i>\/var\/grafana\/plugins\/&lt;your_plugin_name&gt;\/dist\/module.js<\/i>) och kan laddas som ett SystemJS-modul. I denna katalog b\u00f6r det ocks\u00e5 finnas en fil plugin.json som inneh\u00e5ller all metadata om din plugin: namn, version, typ av plugin, l\u00e4nkar till repository\/sajt\/licens, beroenden och s\u00e5 vidare.<\/p>\n<p><img decoding=\"async\" alt=\"Utveckling av plugin f\u00f6r Grafana: en historia av samlade erfarenheter\" src=\"\/wp-content\/uploads\/2019\/11\/5993fec77a3904ed8b9e19a5addbb6ea.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<i>module.ts<\/i><\/p>\n<p><img decoding=\"async\" alt=\"Utveckling av plugin f\u00f6r Grafana: en historia av samlade erfarenheter\" src=\"\/wp-content\/uploads\/2019\/11\/1e5b780837e5a9385e5e22a27d83f567.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<i>plugin.json<\/i><\/p>\n<p>Som visas i sk\u00e4rmdumpen har vi angett plugin.type = app. Plugins f\u00f6r Grafana kan vara av tre typer:<\/p>\n<p><b>panel<\/b>: den vanligaste typen av plugin \u2014 representerar en panel f\u00f6r visualisering av olika metrik, anv\u00e4nds f\u00f6r att bygga olika dashboards.<br \/>\n<b>datasource<\/b>: plugin-anslutning till en datak\u00e4lla (till exempel Prometheus-datasource, ClickHouse-datasource, ElasticSearch-datasource).<br \/>\n<b>app<\/b>: ett plugin som l\u00e5ter dig bygga din egen frontend-applikation inom Grafana, skapa dina egna html-sidor och manuellt g\u00f6ra anslutningar till datak\u00e4llor f\u00f6r att visualisera olika data. Andra typer av plugins (datasource, panel) och olika dashboards kan ocks\u00e5 anv\u00e4ndas som beroenden.<\/p>\n<p><img decoding=\"async\" alt=\"Utveckling av plugin f\u00f6r Grafana: en historia av samlade erfarenheter\" src=\"\/wp-content\/uploads\/2019\/11\/3cd53c7c3a2635f3f20831d52198b5f0.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<i>Exempel p\u00e5 beroenden f\u00f6r plugin med type = app<\/i>.<\/p>\n<p>Som programmeringsspr\u00e5k kan b\u00e5de JavaScript och TypeScript anv\u00e4ndas (vi valde det senare). Mallar f\u00f6r hello-world plugins av alla typer kan <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/CorpGlory\">hittas via l\u00e4nken<\/a><\/noindex>: i detta repository finns ett stort antal starter-paket (det finns till och med ett experimentellt exempel p\u00e5 en plugin i React) med f\u00f6rinstallerade och konfigurerade byggverktyg. <\/p>\n<h4>Del 2: f\u00f6rberedelse av den lokala milj\u00f6n<\/h4>\n<p>\nF\u00f6r att arbeta med pluginet beh\u00f6ver vi naturligtvis en Kubernetes-kluster med alla f\u00f6rinstallerade verktyg: prometheus, node-exporter, kube-state-metrics, grafana. Milj\u00f6n b\u00f6r s\u00e4ttas upp snabbt, enkelt och utan problem, och f\u00f6r att s\u00e4kerst\u00e4lla hot-reload b\u00f6r datakatalogen f\u00f6r Grafana monteras direkt fr\u00e5n utvecklarens maskin.<\/p>\n<p>Det mest bekv\u00e4ma s\u00e4ttet att arbeta lokalt med Kubernetes, enligt v\u00e5r mening, \u00e4r <noindex><a rel=\"nofollow\" href=\"https:\/\/kubernetes.io\/docs\/tasks\/tools\/install-minikube\/\">minikube<\/a><\/noindex>. N\u00e4sta steg \u00e4r att installera Prometheus + Grafana med hj\u00e4lp av prometheus-operator. I <noindex><a rel=\"nofollow\" href=\"https:\/\/medium.com\/faun\/trying-prometheus-operator-with-helm-minikube-b617a2dccfa3\">denna artikel<\/a><\/noindex> beskrivs installationsprocessen f\u00f6r prometheus-operator p\u00e5 minikube i detalj. F\u00f6r att aktivera persistens m\u00e5ste parametern <i>persistence: true<\/i> i filen charts\/grafana\/values.yaml, l\u00f6sa din egen PV och PVC och ange dem i parameter persistence.existingClaim<\/p>\n<p>Det slutgiltiga startskriptet f\u00f6r minikube ser ut s\u00e5 h\u00e4r:<\/p>\n<pre><code class=\"plaintext\">minikube start --kubernetes-version=v1.13.4 --memory=4096 --bootstrapper=kubeadm --extra-config=scheduler.address=0.0.0.0 --extra-config=controller-manager.address=0.0.0.0\nminikube mount \n\/home\/sergeisporyshev\/Projects\/Grafana:\/var\/grafana --gid=472 --uid=472 --9p-version=9p2000.L<\/code><\/pre>\n<p><\/p>\n<h4>Del 3: direkt utveckling<\/h4>\n<p>\n<b>Objektmodell<\/b><\/p>\n<p>Som f\u00f6rberedelse f\u00f6r att implementera pluginen har vi beslutat att beskriva alla grundl\u00e4ggande entiteter i Kubernetes som vi kommer att arbeta med i form av TypeScript-klasser: pod, deployment, daemonset, statefulset, job, cronjob, service, node, namespace. Varje klass \u00e4rver fr\u00e5n en gemensam klass BaseModel, d\u00e4r konstrukt\u00f6r, destrukt\u00f6r, metoder f\u00f6r uppdatering och visningsv\u00e4xling beskrivs. I varje klass beskrivs inb\u00e4ddade relationer med andra entiteter, till exempel listan \u00f6ver poddar i en deployment-entitet.<\/p>\n<pre><code class=\"plaintext\">import {Pod} from \".\/pod\";\nimport {Service} from \".\/service\";\nimport {BaseModel} from '.\/traits\/baseModel';\n\nexport class Deployment extends BaseModel{\n   pods: Array;\n   services: Array;\n\n   constructor(data: any){\n       super(data);\n       this.pods = [];\n       this.services = [];\n   }\n}<\/code><\/pre>\n<p>\nMed hj\u00e4lp av getters och setters kan vi visa eller st\u00e4lla in de m\u00e4tv\u00e4rden f\u00f6r entiteter vi beh\u00f6ver p\u00e5 ett bekv\u00e4mt och l\u00e4sbart s\u00e4tt. Till exempel, formaterad utmatning av allocatable cpu f\u00f6r noden:<\/p>\n<pre><code class=\"plaintext\">get cpuAllocatableFormatted(){\n   let cpu = this.data.status.allocatable.cpu;\n   if(cpu.indexOf('m') &gt; -1){\n       cpu = parseInt(cpu)\/1000;\n   }\n   return cpu;\n}<\/code><\/pre>\n<p>\n<b>Sidor<\/b><\/p>\n<p>Listan \u00f6ver alla sidor i v\u00e5r plugin beskrivs ursprungligen i v\u00e5r pluing.json i avsnittet f\u00f6r beroenden:<\/p>\n<p><img decoding=\"async\" alt=\"Utveckling av plugin f\u00f6r Grafana: en historia av samlade erfarenheter\" src=\"\/wp-content\/uploads\/2019\/11\/b86c74839ad0d9c64b97ffc3f2a84bdf.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nI blocket f\u00f6r varje sida m\u00e5ste vi ange SIDNAMN (det kommer sedan att konverteras till slug, vilket \u00e4r hur denna sida kommer att vara tillg\u00e4nglig); namnet p\u00e5 komponenten som ansvarar f\u00f6r funktionen p\u00e5 denna sida (listan \u00f6ver komponenter exporteras i module.ts); ange vilken anv\u00e4ndarroll som har tillg\u00e5ng till att arbeta med denna sida och inst\u00e4llningarna f\u00f6r navigation i sidopanelen. <\/p>\n<p>I komponenten som ansvarar f\u00f6r sidan m\u00e5ste vi st\u00e4lla in templateUrl och ange s\u00f6kv\u00e4gen till html-filen med markup. Inom controllern, genom dependency injection, kan vi f\u00e5 tillg\u00e5ng till 2 viktiga Angular-tj\u00e4nster:<\/p>\n<ul>\n<li>backendSrv \u2014 tj\u00e4nsten som m\u00f6jligg\u00f6r interaktion med api-servern f\u00f6r Grafana;<\/li>\n<li>datasourceSrv \u2014 tj\u00e4nsten som m\u00f6jligg\u00f6r lokal interaktion med alla datak\u00e4llor som \u00e4r installerade i din Grafana (till exempel, metoden .getAll() \u2014 returnerar en lista \u00f6ver alla installerade datak\u00e4llor; .get() \u2014 returnerar objektinstansen av en specifik datak\u00e4lla.<\/li>\n<\/ul>\n<p>\n<img decoding=\"async\" alt=\"Utveckling av plugin f\u00f6r Grafana: en historia av samlade erfarenheter\" src=\"\/wp-content\/uploads\/2019\/11\/e616e74c2e31ca3a81b7ed91ca333208.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\n<img decoding=\"async\" alt=\"Utveckling av plugin f\u00f6r Grafana: en historia av samlade erfarenheter\" src=\"\/wp-content\/uploads\/2019\/11\/5e1d45f570dda50774088405abb41c9f.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\n<img decoding=\"async\" alt=\"Utveckling av plugin f\u00f6r Grafana: en historia av samlade erfarenheter\" src=\"\/wp-content\/uploads\/2019\/11\/c072867623824e799518984c7b1bee93.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<\/p>\n<h4>Del 4: datak\u00e4lla<\/h4>\n<p>\nFr\u00e5n Grafanas perspektiv representerar en datasourc exakt samma typ av plugin som alla andra: den har en ing\u00e5ngspunkt module.js och en fil med metadata plugin.json. N\u00e4r vi utvecklar ett plugin med typ = app kan vi interagera b\u00e5de med befintliga datasourcer (till exempel prometheus-datasource) och med egna som vi kan lagra direkt i pluginets katalog (dist\/datasource\/*) eller installera som beroende. I v\u00e5rt fall levereras datasourcen tillsammans med pluginets kod. Det \u00e4r ocks\u00e5 n\u00f6dv\u00e4ndigt att ha en mall config.html och kontrollern ConfigCtrl, som kommer att anv\u00e4ndas f\u00f6r konfigureringssidan av datasourc-exemplaret och kontrollern Datasource, d\u00e4r logiken f\u00f6r din datasources funktionalitet implementeras.<\/p>\n<p>I KubeGraf-pluginet, fr\u00e5n anv\u00e4ndargr\u00e4nssnittets perspektiv, representerar en datasourc ett exempel p\u00e5 en Kubernetes-kluster, d\u00e4r f\u00f6ljande funktioner \u00e4r implementerade (k\u00e4llkoden \u00e4r tillg\u00e4nglig <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/devopsprodigy\/kubegraf\/tree\/master\/src\/datasource\">via l\u00e4nken<\/a><\/noindex>):<\/p>\n<ul>\n<li>h\u00e4mtning av data fr\u00e5n k8s api-server (h\u00e4mtning av listor \u00f6ver namespaces, deployments\u2026)<\/li>\n<li>proxying av f\u00f6rfr\u00e5gningar till prometheus-datasource (som v\u00e4ljs i plugininst\u00e4llningarna f\u00f6r varje specifikt kluster) och formatering av svar f\u00f6r att anv\u00e4nda data b\u00e5de p\u00e5 statiska sidor och i dashboards.<\/li>\n<li>uppdatering av data p\u00e5 statiska sidor i pluginet (med inst\u00e4lld uppdateringsfrekvens).<\/li>\n<li>bearbetning av f\u00f6rfr\u00e5gningar f\u00f6r att skapa template-listor i grafana-dashboards (metod .metriFindQuery())<\/li>\n<\/ul>\n<p>\n<img decoding=\"async\" alt=\"Utveckling av plugin f\u00f6r Grafana: en historia av samlade erfarenheter\" src=\"\/wp-content\/uploads\/2019\/11\/18159bbb41144ebceb457df28b35e7b1.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\n<img decoding=\"async\" alt=\"Utveckling av plugin f\u00f6r Grafana: en historia av samlade erfarenheter\" src=\"\/wp-content\/uploads\/2019\/11\/a62665b4409566fbe24f56f88a376d5a.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\n<img decoding=\"async\" alt=\"Utveckling av plugin f\u00f6r Grafana: en historia av samlade erfarenheter\" src=\"\/wp-content\/uploads\/2019\/11\/7f2d61fce623ce2a3cf62feb6d0447ac.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<\/p>\n<ul>\n<li>test av anslutning till den slutgiltiga k8s-klustret.<\/li>\n<\/ul>\n<pre><code class=\"plaintext\">testDatasource(){\n   let url = '\/api\/v1\/namespaces';\n   let _url = this.url;\n   if(this.accessViaToken)\n       _url += '\/__proxy';\n   _url += url;\n   return this.backendSrv.datasourceRequest({\n       url: _url,\n       method: \"GET\",\n       headers: {\"Content-Type\": 'application\/json'}\n   })\n       .then(response =&gt; {\n           if (response.status === 200) {\n               return {status: \"success\", message: \"Data source is OK\", title: \"Success\"};\n           }else{\n               return {status: \"error\", message: \"Data source is not OK\", title: \"Error\"};\n           }\n       }, error =&gt; {\n           return {status: \"error\", message: \"Data source is not OK\", title: \"Error\"};\n       })\n}<\/code><\/pre>\n<p>\nEnligt v\u00e5r \u00e5sikt \u00e4r en intressant aspekt implementeringen av autentisering och auktorisering f\u00f6r datasource. Vanligtvis kan vi anv\u00e4nda den inbyggda komponenten datasourceHttpSettings i Grafana f\u00f6r att konfigurera \u00e5tkomst till den slutliga datak\u00e4llan. Med denna komponent kan vi st\u00e4lla in \u00e5tkomst till http-datak\u00e4llan genom att ange URL och grundl\u00e4ggande autentisering\/Auktorisering: anv\u00e4ndarnamn-l\u00f6senord, eller client-cert\/client-key. F\u00f6r att m\u00f6jligg\u00f6ra \u00e5tkomstkonfiguration med ett bearer-token (de facto-standarden f\u00f6r k8s) var vi tvungna att g\u00f6ra lite \"magik\".<\/p>\n<p>F\u00f6r att l\u00f6sa detta problem kan den inbyggda mekanismen \"Plugin Routes\" i Grafana anv\u00e4ndas (mer information finns p\u00e5 <noindex><a rel=\"nofollow\" href=\"https:\/\/grafana.com\/docs\/plugins\/developing\/auth-for-datasources\/\">den officiella dokumentationssidan<\/a><\/noindex>). I inst\u00e4llningarna f\u00f6r v\u00e5r datasource kan vi deklarera en upps\u00e4ttning routingregler som kommer att hanteras av grafana proxy-servern. Till exempel finns det f\u00f6r varje separat endpoint m\u00f6jlighet att ange rubriker eller URL med templatering, vars data kan h\u00e4mtas fr\u00e5n f\u00e4lten jsonData och secureJsonData (f\u00f6r att lagra l\u00f6senord eller tokens i krypterad form). I v\u00e5rt exempel kommer f\u00f6rfr\u00e5gningar av typen <i>\/__proxy\/api\/v1\/namespaces<\/i> att proxas till URL av typen<br \/>\n\/api\/v1\/namespaces med att rubriken Authorization: Bearer anger.<\/p>\n<p><img decoding=\"async\" alt=\"Utveckling av plugin f\u00f6r Grafana: en historia av samlade erfarenheter\" src=\"\/wp-content\/uploads\/2019\/11\/ca73ff0fef62fba3edab7907c83639b6.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\n<img decoding=\"async\" alt=\"Utveckling av plugin f\u00f6r Grafana: en historia av samlade erfarenheter\" src=\"\/wp-content\/uploads\/2019\/11\/9dab7537d7ccba90c9fb62dfa70b9fe2.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nSj\u00e4lvklart beh\u00f6ver vi en anv\u00e4ndare med readonly \u00e5tkomst f\u00f6r att arbeta med k8s api-servern, och manifest f\u00f6r att skapa den kan du ocks\u00e5 hitta i <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/devopsprodigy\/kubegraf\/tree\/master\/kubernetes\/\">pluginens k\u00e4llkod<\/a><\/noindex>.<\/p>\n<h4>Del 5: release<\/h4>\n<p>\n<img decoding=\"async\" alt=\"Utveckling av plugin f\u00f6r Grafana: en historia av samlade erfarenheter\" src=\"\/wp-content\/uploads\/2019\/11\/3991a5d412f362770157fc567bb8009c.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nEfter att du har skrivit din egen plugin f\u00f6r Grafana kommer du sj\u00e4lvklart vilja publicera den offentligt. I Grafana finns det ett pluginbibliotek som \u00e4r tillg\u00e4ngligt via l\u00e4nken <noindex><a rel=\"nofollow\" href=\"https:\/\/grafana.com\/grafana\/plugins\">grafana.com\/grafana\/plugins<\/a><\/noindex> <\/p>\n<p>F\u00f6r att din plugin ska vara tillg\u00e4nglig i den officiella butiken m\u00e5ste du g\u00f6ra en PR i <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/grafana\/grafana-plugin-repository\">detta repository<\/a><\/noindex>, genom att l\u00e4gga till inneh\u00e5llet av typen i filen repo.json:<\/p>\n<p><img decoding=\"async\" alt=\"Utveckling av plugin f\u00f6r Grafana: en historia av samlade erfarenheter\" src=\"\/wp-content\/uploads\/2019\/11\/160650bf37f8f2f3e12ef7dd291e90eb.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nd\u00e4r version - versionen av din plugin, url - l\u00e4nk till ditt repository, och commit - hash f\u00f6r den commit som den specifika versionen av pluginen kommer att vara tillg\u00e4nglig. <\/p>\n<p>Och till slut kommer du att se en underbar bild av typen:<\/p>\n<p><img decoding=\"async\" alt=\"Utveckling av plugin f\u00f6r Grafana: en historia av samlade erfarenheter\" src=\"\/wp-content\/uploads\/2019\/11\/ff906396596e9c4c15c59f8d53555f52.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nData f\u00f6r den kommer automatiskt att samlas in fr\u00e5n din Readme.md, Changelog.md och plugin.json-filens beskrivning av pluginen.<\/p>\n<h4>Del 6: sammanfattning<\/h4>\n<p>\nVi har inte slutat utveckla v\u00e5r plugin efter lanseringen. Just nu arbetar vi med korrekt \u00f6vervakning av resursanv\u00e4ndningen av noderna i klustret, inf\u00f6randet av nya funktioner f\u00f6r att f\u00f6rb\u00e4ttra anv\u00e4ndarupplevelsen samt att bearbeta m\u00e4ngder av feedback som vi har f\u00e5tt efter installationer av pluginet, b\u00e5de fr\u00e5n v\u00e5ra kunder och genom issues p\u00e5 GitHub (om du l\u00e4mnar en issue eller pull request blir jag mycket glad \ud83d\ude42 ).<\/p>\n<p>Vi hoppas att denna artikel hj\u00e4lper dig att f\u00f6rst\u00e5 det fantastiska verktyget Grafana och kanske skriva din egen plugin. <\/p>\n<p>Tack!)<br \/>\n<br \/>K\u00e4lla: <a content=\"nofollow\" rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/company\/itsumma\/blog\/474500\/\">habr.com<\/a><\/p>","protected":false,"gt_translate_keys":[{"key":"rendered","format":"html"}]},"excerpt":{"rendered":"<p>\u0412\u0441\u0435\u043c \u043f\u0440\u0438\u0432\u0435\u0442! \u041d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u043c\u0435\u0441\u044f\u0446\u0435\u0432 \u043d\u0430\u0437\u0430\u0434 \u043c\u044b \u0437\u0430\u043f\u0443\u0441\u0442\u0438\u043b\u0438 \u0432 \u043f\u0440\u043e\u0434\u0430\u043a\u0448\u043d \u043d\u0430\u0448 \u043d\u043e\u0432\u044b\u0439 open-source \u043f\u0440\u043e\u0435\u043a\u0442 \u2014 Grafana-\u043f\u043b\u0430\u0433\u0438\u043d \u0434\u043b\u044f \u043c\u043e\u043d\u0438\u0442\u043e\u0440\u0438\u043d\u0433\u0430 kubernetes, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043d\u0430\u0437\u0432\u0430\u043b\u0438 DevOpsProdigy KubeGraf. \u0418\u0441\u0445\u043e\u0434\u043d\u044b\u0439 \u043a\u043e\u0434 \u043f\u043b\u0430\u0433\u0438\u043d\u0430 \u0434\u043e\u0441\u0442\u0443\u043f\u0435\u043d \u0432 \u043f\u0443\u0431\u043b\u0438\u0447\u043d\u043e\u043c \u0440\u0435\u043f\u043e\u0437\u0438\u0442\u043e\u0440\u0438\u0438 \u043d\u0430 GitHub. \u0410 \u0432 \u044d\u0442\u043e\u0439 \u0441\u0442\u0430\u0442\u044c\u0435 \u043c\u044b \u0445\u043e\u0442\u0438\u043c \u043f\u043e\u0434\u0435\u043b\u0438\u0442\u044c\u0441\u044f \u0441 \u0432\u0430\u043c\u0438 \u0438\u0441\u0442\u043e\u0440\u0438\u0435\u0439 \u043e \u0442\u043e\u043c, \u043a\u0430\u043a \u043c\u044b \u0441\u043e\u0437\u0434\u0430\u0432\u0430\u043b\u0438 \u043f\u043b\u0430\u0433\u0438\u043d, \u043a\u0430\u043a\u0438\u0435 \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442\u044b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043b\u0438 \u0438 \u0441 \u043a\u0430\u043a\u0438\u043c\u0438 \u043f\u043e\u0434\u0432\u043e\u0434\u043d\u044b\u043c\u0438 \u043a\u0430\u043c\u043d\u044f\u043c\u0438 [&hellip;]<\/p>\n","protected":false,"gt_translate_keys":[{"key":"rendered","format":"html"}]},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[688],"tags":[],"class_list":["post-52343","post","type-post","status-publish","format-standard","hentry","category-administrirovanie"],"aioseo_notices":[],"aioseo_head":"\n\t\t<!-- All in One SEO 5.0.4 - aioseo.com -->\n\t<meta name=\"description\" content=\"\u0412\u0441\u0435\u043c \u043f\u0440\u0438\u0432\u0435\u0442!\" \/>\n\t<meta name=\"robots\" content=\"max-image-preview:large\" \/>\n\t<meta name=\"author\" content=\"Yuri Gagarin\"\/>\n\t<link rel=\"canonical\" href=\"https:\/\/prohoster.info\/sv\/blog\/administrirovanie\/razrabotka-plagina-dlya-grafana-istoriya-nabityh-shishek\" \/>\n\t\t<meta name=\"generator\" content=\"All in One SEO (AIOSEO) 5.0.4\" \/>\n\t\t<meta property=\"og:locale\" content=\"sv_SE\" \/>\n\t\t<meta property=\"og:site_name\" content=\"ProHoster | \u041a\u0443\u043f\u0438\u0442\u044c \u043d\u0430\u0434\u0435\u0436\u043d\u044b\u0439 \u0445\u043e\u0441\u0442\u0438\u043d\u0433 \u0434\u043b\u044f \u0441\u0430\u0439\u0442\u043e\u0432 \u0441 \u0437\u0430\u0449\u0438\u0442\u043e\u0439 \u043e\u0442 DDoS, VPS VDS \u0441\u0435\u0440\u0432\u0435\u0440\u044b\" \/>\n\t\t<meta property=\"og:type\" content=\"article\" \/>\n\t\t<meta property=\"og:title\" content=\"\ud83e\udd47\u0420\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0430 \u043f\u043b\u0430\u0433\u0438\u043d\u0430 \u0434\u043b\u044f Grafana: \u0438\u0441\u0442\u043e\u0440\u0438\u044f \u043d\u0430\u0431\u0438\u0442\u044b\u0445 \u0448\u0438\u0448\u0435\u043a | ProHoster\" \/>\n\t\t<meta property=\"og:description\" content=\"\u0412\u0441\u0435\u043c \u043f\u0440\u0438\u0432\u0435\u0442!\" \/>\n\t\t<meta property=\"og:url\" content=\"https:\/\/prohoster.info\/sv\/blog\/administrirovanie\/razrabotka-plagina-dlya-grafana-istoriya-nabityh-shishek\" \/>\n\t\t<meta property=\"og:image\" content=\"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg\" \/>\n\t\t<meta property=\"og:image:secure_url\" content=\"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg\" \/>\n\t\t<meta property=\"og:image:width\" content=\"350\" \/>\n\t\t<meta property=\"og:image:height\" content=\"350\" \/>\n\t\t<meta property=\"article:published_time\" content=\"2019-11-05T21:00:00+00:00\" \/>\n\t\t<meta property=\"article:modified_time\" content=\"2020-02-18T11:00:02+00:00\" \/>\n\t\t<meta property=\"article:publisher\" content=\"https:\/\/www.facebook.com\/prohoster\" \/>\n\t\t<meta property=\"article:author\" content=\"https:\/\/www.facebook.com\/prohoster\" \/>\n\t\t<!-- All in One SEO -->\n\n","aioseo_head_json":{"title":"\ud83e\udd47Utveckling av plugin f\u00f6r Grafana: historien bakom motg\u00e5ngarna | ProHoster","description":"Hej alla!","canonical_url":"https:\/\/prohoster.info\/sv\/blog\/administrirovanie\/razrabotka-plagina-dlya-grafana-istoriya-nabityh-shishek","robots":"max-image-preview:large","keywords":"","webmasterTools":{"miscellaneous":""},"schema":null,"og:locale":"sv_SE","og:site_name":"ProHoster | \u041a\u0443\u043f\u0438\u0442\u044c \u043d\u0430\u0434\u0435\u0436\u043d\u044b\u0439 \u0445\u043e\u0441\u0442\u0438\u043d\u0433 \u0434\u043b\u044f \u0441\u0430\u0439\u0442\u043e\u0432 \u0441 \u0437\u0430\u0449\u0438\u0442\u043e\u0439 \u043e\u0442 DDoS, VPS VDS \u0441\u0435\u0440\u0432\u0435\u0440\u044b","og:type":"article","og:title":"\ud83e\udd47\u0420\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0430 \u043f\u043b\u0430\u0433\u0438\u043d\u0430 \u0434\u043b\u044f Grafana: \u0438\u0441\u0442\u043e\u0440\u0438\u044f \u043d\u0430\u0431\u0438\u0442\u044b\u0445 \u0448\u0438\u0448\u0435\u043a | ProHoster","og:description":"\u0412\u0441\u0435\u043c \u043f\u0440\u0438\u0432\u0435\u0442!","og:url":"https:\/\/prohoster.info\/sv\/blog\/administrirovanie\/razrabotka-plagina-dlya-grafana-istoriya-nabityh-shishek","og:image":"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg","og:image:secure_url":"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg","og:image:width":350,"og:image:height":350,"article:published_time":"2019-11-05T21:00:00+00:00","article:modified_time":"2020-02-18T11:00:02+00:00","article:publisher":"https:\/\/www.facebook.com\/prohoster","article:author":"https:\/\/www.facebook.com\/prohoster"},"aioseo_meta_data":{"post_id":"52343","title":null,"description":null,"keywords":null,"keyphrases":null,"primary_term":null,"canonical_url":null,"og_title":null,"og_description":null,"og_object_type":"default","og_image_type":"default","og_image_url":null,"og_image_width":null,"og_image_height":null,"og_image_custom_url":null,"og_image_custom_fields":null,"og_video":null,"og_custom_url":null,"og_article_section":null,"og_article_tags":null,"twitter_use_og":false,"twitter_card":"default","twitter_image_type":"default","twitter_image_url":null,"twitter_image_custom_url":null,"twitter_image_custom_fields":null,"twitter_title":null,"twitter_description":null,"schema":{"blockGraphs":[],"customGraphs":[],"default":{"data":{"Article":[],"Course":[],"Dataset":[],"FAQPage":[],"Movie":[],"Person":[],"Product":[],"ProductReview":[],"Car":[],"Recipe":[],"Service":[],"SoftwareApplication":[],"WebPage":[]},"graphName":"","isEnabled":true},"graphs":[]},"schema_type":null,"schema_type_options":null,"pillar_content":false,"robots_default":true,"robots_noindex":false,"robots_noarchive":false,"robots_nosnippet":false,"robots_nofollow":false,"robots_noimageindex":false,"robots_noodp":false,"robots_notranslate":false,"robots_max_snippet":null,"robots_max_videopreview":null,"robots_max_imagepreview":"large","priority":null,"frequency":null,"local_seo":null,"seo_analyzer_scan_date":"2026-01-24 03:18:19","breadcrumb_settings":null,"limit_modified_date":false,"reviewed_by":null,"ai":null,"created":"2021-02-28 20:45:28","updated":"2026-01-24 03:18:19","focus_keyword":null,"additional_keywords":null,"truseo_locale":null},"gt_translate_keys":[{"key":"link","format":"url"}],"_links":{"self":[{"href":"https:\/\/prohoster.info\/sv\/wp-json\/wp\/v2\/posts\/52343","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/prohoster.info\/sv\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/prohoster.info\/sv\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/prohoster.info\/sv\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/prohoster.info\/sv\/wp-json\/wp\/v2\/comments?post=52343"}],"version-history":[{"count":0,"href":"https:\/\/prohoster.info\/sv\/wp-json\/wp\/v2\/posts\/52343\/revisions"}],"wp:attachment":[{"href":"https:\/\/prohoster.info\/sv\/wp-json\/wp\/v2\/media?parent=52343"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/prohoster.info\/sv\/wp-json\/wp\/v2\/categories?post=52343"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/prohoster.info\/sv\/wp-json\/wp\/v2\/tags?post=52343"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}