{"id":205,"date":"2017-12-11T13:57:16","date_gmt":"2017-12-11T12:57:16","guid":{"rendered":"https:\/\/corsaire-consulting.fr\/blog\/?p=205"},"modified":"2017-12-11T13:57:16","modified_gmt":"2017-12-11T12:57:16","slug":"monitoring-jvm-avec-prometheus","status":"publish","type":"post","link":"https:\/\/corsaire-consulting.fr\/blog\/index.php\/2017\/12\/11\/monitoring-jvm-avec-prometheus\/","title":{"rendered":"Monitoring JVM avec Prometheus"},"content":{"rendered":"<p>Cet article pr\u00e9sente comment superviser des JVMs gr\u00e2ce \u00e0 la solution open-source <a href=\"https:\/\/prometheus.io\/\">Prometheus<\/a>.<\/p>\n<p>Ce produit s&rsquo;apparente \u00e0 une solution de supervision et d&rsquo;alerte des composants r\u00e9guli\u00e8rement rencontr\u00e9s dans un SI : bases de donn\u00e9es, MOM, syst\u00e8mes de fichiers, r\u00e9partiteurs\u00a0 de charge, serveurs d&rsquo;application, serveurs HTTP, etc&#8230;<\/p>\n<p>Le produit r\u00e9cup\u00e8res les infos aupr\u00e8s des diff\u00e9rents composants qu&rsquo;il supervise et les stocke dans sa base de donn\u00e9es de s\u00e9ries chronologiques (time-series database)<\/p>\n<p><!--more--><\/p>\n<p>La suite de l&rsquo;article montre comment configurer Prom\u00e9theus pour superviser un serveur WebLogic.<\/p>\n<p>Prometheus interroge l&rsquo;instance WebLogic Server afin de r\u00e9cup\u00e9rer les m\u00e9triques pour les stocker dans sa base.<\/p>\n<p>&nbsp;<\/p>\n<h1>Installation<\/h1>\n<p><a href=\"https:\/\/prometheus.io\/download\/\">T\u00e9l\u00e9charger<\/a> et installer le produit en suivant ces <a href=\"https:\/\/prometheus.io\/docs\/prometheus\/latest\/installation\/\">instructions<\/a>.<\/p>\n<p>&nbsp;<\/p>\n<h1>Configuration de Prometheus<\/h1>\n<p>La configuration s&rsquo;effectue dans le fichier de configuration YAML prometheus.yml situ\u00e9 \u00e0 la racine de l&rsquo;installation de Prometheus.<\/p>\n<p>[pastacode lang=\u00a0\u00bbhaml\u00a0\u00bb manual=\u00a0\u00bb%23%20my%20global%20config%0Aglobal%3A%0A%20%20scrape_interval%3A%20%20%20%20%2015s%20%23%20Set%20the%20scrape%20interval%20to%20every%2015%20seconds.%20Default%20is%20every%201%20minute.%0A%20%20evaluation_interval%3A%2015s%20%23%20Evaluate%20rules%20every%2015%20seconds.%20The%20default%20is%20every%201%20minute.%0A%20%20%23%20scrape_timeout%20is%20set%20to%20the%20global%20default%20(10s).%0A%0A%23%20Alertmanager%20configuration%0Aalerting%3A%0A%20%20alertmanagers%3A%0A%20%20-%20static_configs%3A%0A%20%20%20%20-%20targets%3A%0A%20%20%20%20%20%20%23%20-%20alertmanager%3A9093%0A%0A%23%20Load%20rules%20once%20and%20periodically%20evaluate%20them%20according%20to%20the%20global%20&rsquo;evaluation_interval&rsquo;.%0Arule_files%3A%0A%20%20%23%20-%20%22first_rules.yml%22%0A%20%20%23%20-%20%22second_rules.yml%22%0A%0A%23%20A%20scrape%20configuration%20containing%20exactly%20one%20endpoint%20to%20scrape%3A%0A%23%20Here%20it&rsquo;s%20Prometheus%20itself.%0Ascrape_configs%3A%0A%20%20%23%20The%20job%20name%20is%20added%20as%20a%20label%20%60job%3D%3Cjob_name%3E%60%20to%20any%20timeseries%20scraped%20from%20this%20config.%0A%20%20-%20job_name%3A%20&rsquo;weblogic&rsquo;%0A%0A%20%20%20%20%23%20metrics_path%20defaults%20to%20&rsquo;%2Fmetrics&rsquo;%0A%20%20%20%20%23%20scheme%20defaults%20to%20&rsquo;http&rsquo;.%0A%20%20%20%20metrics_path%3A%20%2Fmetrics%0A%20%20%20%20static_configs%3A%0A%20%20%20%20%20%20-%20targets%3A%20%5B&rsquo;localhost%3A7001&rsquo;%5D\u00a0\u00bb message=\u00a0\u00bbConfiguration de Prometheus\u00a0\u00bb highlight=\u00a0\u00bb\u00a0\u00bb provider=\u00a0\u00bbmanual\u00a0\u00bb\/]<\/p>\n<p>Le job \u00ab\u00a0weblogic\u00a0\u00bb d\u00e9finit les composants \u00e0 superviser (targets). Dans notre exemple, il sagit d&rsquo;un serveur WebLogic Server qui \u00e9coute sur le port 7001.<\/p>\n<p>Prometheus interrogera l&rsquo;URL http:\/\/localhost:7001\/metrics pour r\u00e9cup\u00e9rer les m\u00e9triques toutes les 15 secondes.<\/p>\n<p>Le context root \/metrics correspond \u00e0 une Servlet d\u00e9ploy\u00e9e dans le serveur WebLogic. Son code est fournit ci-apr\u00e8s.<\/p>\n<h1>Servlet \/metrics<\/h1>\n<p>&nbsp;<\/p>\n<p>La servlet r\u00e9cup\u00e8res les informations aupr\u00e8s de MBeans JMX et les expose via la m\u00e9thode service() qui sera invoqu\u00e9e par Prometheus.<\/p>\n<p>L&rsquo;exemple donn\u00e9 ci-apr\u00e8s remonte la m\u00e9moire disponible ainsi que la capacit\u00e9 maximale actuelle de la HEAP de la JVM.<\/p>\n<p>&nbsp;<\/p>\n<h2>Code source<\/h2>\n<p>[pastacode lang=\u00a0\u00bbjava\u00a0\u00bb manual=\u00a0\u00bbpackage%20fr.corsaireconsulting.metrics%3B%0A%0Aimport%20java.io.IOException%3B%0Aimport%20java.io.PrintWriter%3B%0Aimport%20java.lang.management.ManagementFactory%3B%0A%0Aimport%20javax.management.AttributeNotFoundException%3B%0Aimport%20javax.management.InstanceNotFoundException%3B%0Aimport%20javax.management.MBeanException%3B%0Aimport%20javax.management.MBeanServer%3B%0Aimport%20javax.management.MalformedObjectNameException%3B%0Aimport%20javax.management.ObjectName%3B%0Aimport%20javax.management.ReflectionException%3B%0Aimport%20javax.servlet.ServletException%3B%0Aimport%20javax.servlet.http.HttpServlet%3B%0Aimport%20javax.servlet.http.HttpServletRequest%3B%0Aimport%20javax.servlet.http.HttpServletResponse%3B%0A%0A%2F**%0A%20*%20Servlet%20implementation%20class%20PrometheusExporter%0A%20*%2F%0Apublic%20class%20PrometheusExporter%20extends%20HttpServlet%20%7B%0A%09private%20static%20final%20long%20serialVersionUID%20%3D%201L%3B%0A%09%0A%09private%20MBeanServer%20mbs%20%3D%20null%3B%0A%09private%20String%20domainName%20%3D%20null%3B%0A%09private%20String%20serverName%20%3D%20null%3B%0A%09private%20javax.management.ObjectName%20jvmRuntime%20%3D%20null%3B%0A%20%20%20%20%2F**%0A%20%20%20%20%20*%20%40see%20HttpServlet%23HttpServlet()%0A%20%20%20%20%20*%2F%0A%20%20%20%20public%20PrometheusExporter()%20%7B%0A%20%20%20%20%20%20%20%20super()%3B%0A%20%20%20%20%7D%0A%20%20%20%20%0A%20%20%20%20private%20void%20trace(String%20message)%20%7B%0A%20%20%20%20%09System.out.println(%22PrometheusExporter%3A%22%2Bmessage)%3B%0A%20%20%20%20%7D%0A%0A%09%2F**%0A%09%20*%20%40see%20HttpServlet%23doGet(HttpServletRequest%20request%2C%20HttpServletResponse%20response)%0A%09%20*%2F%0A%09protected%20void%20doGet(HttpServletRequest%20request%2C%20HttpServletResponse%20response)%20throws%20ServletException%2C%20IOException%20%7B%0A%09%09service(request%2C%20response)%3B%0A%09%7D%0A%0A%09%2F**%0A%09%20*%20%40see%20HttpServlet%23doPost(HttpServletRequest%20request%2C%20HttpServletResponse%20response)%0A%09%20*%2F%0A%09protected%20void%20doPost(HttpServletRequest%20request%2C%20HttpServletResponse%20response)%20throws%20ServletException%2C%20IOException%20%7B%0A%09%09service(request%2C%20response)%3B%0A%09%7D%20%0A%0A%09%40Override%0A%09protected%20void%20service(HttpServletRequest%20request%2C%20HttpServletResponse%20response)%0A%09%09%09throws%20ServletException%2C%20IOException%20%7B%0A%0A%09%09trace(%22servce.enter%22)%3B%0A%09%09trace(%22Request%20received%22)%3B%0A%09%09trace(request.getMethod()%2B%22%20%22%2Brequest.getQueryString())%3B%09%0A%09%09%0A%09%09response.setContentType(%22text%2Fplain%22)%3B%0A%09%09PrintWriter%20out%20%3D%20response.getWriter()%3B%0A%09%09%0A%09%09try%20%7B%0A%09%09%09Long%20heapFree%20%3D%20(Long)(mbs.getAttribute(jvmRuntime%2C%20%22HeapFreeCurrent%22))%3B%0A%09%09%09Long%20heapCurrent%20%3D%20(Long)(mbs.getAttribute(jvmRuntime%2C%20%22HeapSizeCurrent%22))%3B%0A%09%09%09out.println(%22jvm_heap_free_current%7Bdomain%3D%5C%22%22%2BdomainName%2B%22%5C%22%2Cname%3D%5C%22%22%2BserverName%2B%22%5C%22%7D%20%22%2BheapFree.longValue())%3B%0A%09%09%09out.println(%22jvm_heap_size_current%7Bdomain%3D%5C%22%22%2BdomainName%2B%22%5C%22%2Cname%3D%5C%22%22%2BserverName%2B%22%5C%22%7D%20%22%2BheapCurrent.longValue())%3B%0A%09%09%7D%20catch%20(AttributeNotFoundException%20e)%20%7B%0A%09%09%09e.printStackTrace()%3B%0A%09%09%7D%20catch%20(InstanceNotFoundException%20e)%20%7B%0A%09%09%09e.printStackTrace()%3B%0A%09%09%7D%20catch%20(MBeanException%20e)%20%7B%0A%09%09%09e.printStackTrace()%3B%0A%09%09%7D%20catch%20(ReflectionException%20e)%20%7B%0A%09%09%09e.printStackTrace()%3B%0A%09%09%7D%0A%09%09%0A%09%09%0A%09%09out.flush()%3B%0A%09%09out.close()%3B%0A%09%09trace(%22servce.exit%22)%3B%0A%0A%09%7D%0A%0A%09%40Override%0A%09public%20void%20init()%20throws%20ServletException%20%7B%0A%09%09super.init()%3B%0A%09%09trace(%22init.enter%22)%3B%0A%09%09mbs%20%3D%20ManagementFactory.getPlatformMBeanServer()%3B%0A%09%09%0A%09%09try%20%7B%0A%09%09%09javax.management.ObjectName%20service%20%3D%20new%20javax.management.ObjectName(%22com.bea%3AName%3DRuntimeService%2CType%3Dweblogic.management.mbeanservers.runtime.RuntimeServiceMBean%22)%3B%0A%09%09%09javax.management.ObjectName%20dconf%20%3D%20(javax.management.ObjectName)mbs.getAttribute(service%2C%20%22DomainConfiguration%22)%3B%0A%09%09%09%0A%0A%09%09%09javax.management.ObjectName%20serverConf%20%3D%20(javax.management.ObjectName)mbs.getAttribute(service%2C%20%22ServerRuntime%22)%3B%0A%09%09%09%0A%09%09%09domainName%20%3D%20(String)(mbs.getAttribute(dconf%2C%20%22Name%22))%3B%0A%09%09%09serverName%20%3D%20(String)(mbs.getAttribute(serverConf%2C%20%22Name%22))%3B%0A%09%09%09%0A%09%09%09jvmRuntime%20%3D%20new%20ObjectName(%22com.bea%3AServerRuntime%3D%22%2BserverName%2B%22%2CName%3D%22%2BserverName%2B%22%2CType%3DJRockitRuntime%22)%3B%0A%0A%09%09%09trace(%22domaineName%3A%22%2BdomainName)%3B%0A%09%09%09trace(%22serverName%3A%22%2BserverName)%3B%0A%0A%09%09%7D%20catch%20(MalformedObjectNameException%20e)%20%7B%0A%09%09%09e.printStackTrace()%3B%0A%09%09%7D%20catch%20(NullPointerException%20e)%20%7B%0A%09%09%09e.printStackTrace()%3B%0A%09%09%7D%20catch%20(AttributeNotFoundException%20e)%20%7B%0A%09%09%09e.printStackTrace()%3B%0A%09%09%7D%20catch%20(InstanceNotFoundException%20e)%20%7B%0A%09%09%09e.printStackTrace()%3B%0A%09%09%7D%20catch%20(MBeanException%20e)%20%7B%0A%09%09%09e.printStackTrace()%3B%0A%09%09%7D%20catch%20(ReflectionException%20e)%20%7B%0A%09%09%09e.printStackTrace()%3B%0A%09%09%7D%0A%09%09trace(%22init.exit%22)%3B%0A%09%7D%0A%0A%7D%0A\u00a0\u00bb message=\u00a0\u00bb\u00a0\u00bb highlight=\u00a0\u00bb\u00a0\u00bb provider=\u00a0\u00bbmanual\u00a0\u00bb\/]<\/p>\n<h2>Configuration<\/h2>\n<p>La d\u00e9claration de la servlet dans le fichier web.xml de l&rsquo;application web :<\/p>\n<p>[pastacode lang=\u00a0\u00bbmarkup\u00a0\u00bb manual=\u00a0\u00bb%20%20%3Cservlet%3E%0A%20%20%20%20%3Cdescription%3E%3C%2Fdescription%3E%0A%20%20%20%20%3Cdisplay-name%3EPrometheusExporter%3C%2Fdisplay-name%3E%0A%20%20%20%20%3Cservlet-name%3EPrometheusExporter%3C%2Fservlet-name%3E%0A%20%20%20%20%3Cservlet-class%3Efr.corsaireconsulting.metrics.PrometheusExporter%3C%2Fservlet-class%3E%0A%20%20%3C%2Fservlet%3E%0A%20%20%3Cservlet-mapping%3E%0A%20%20%20%20%3Cservlet-name%3EPrometheusExporter%3C%2Fservlet-name%3E%0A%20%20%20%20%3Curl-pattern%3E%2F*%3C%2Furl-pattern%3E%0A%20%20%3C%2Fservlet-mapping%3E\u00a0\u00bb message=\u00a0\u00bbextrait du fichier web.xml\u00a0\u00bb highlight=\u00a0\u00bb\u00a0\u00bb provider=\u00a0\u00bbmanual\u00a0\u00bb\/]<\/p>\n<p>&nbsp;<\/p>\n<h1>Ex\u00e9cution<\/h1>\n<p>Cr\u00e9er un domaine WebLogic Server avec un seul serveur d&rsquo;administration.<\/p>\n<p>D\u00e9marrer le serveur WevLogic\u00a0 et y d\u00e9ployer l&rsquo;application web (avec la console d&rsquo;administration par exemple)<\/p>\n<p>Lancer le serveur Prometheus.<\/p>\n<p>Prometheus d\u00e9marre directement la capture des donn\u00e9es. V\u00e9rifier dans la sortie standard du serveur WebLogic que la servlet est bien appel\u00e9e par Prometheus.<\/p>\n<p>Lancer la console Prometheus : <a href=\"http:\/\/localhost:9090\/graph\">http:\/\/localhost:9090\/graph<\/a><\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-medium wp-image-231\" src=\"https:\/\/corsaire-consulting.fr\/blog\/wp-content\/uploads\/2017\/11\/prometheus_1-300x224.png\" alt=\"\" width=\"300\" height=\"224\" srcset=\"https:\/\/corsaire-consulting.fr\/blog\/wp-content\/uploads\/2017\/11\/prometheus_1-300x224.png 300w, https:\/\/corsaire-consulting.fr\/blog\/wp-content\/uploads\/2017\/11\/prometheus_1.png 527w\" sizes=\"auto, (max-width: 300px) 100vw, 300px\" \/><\/p>\n<p>&nbsp;<\/p>\n<p>Le reste est histoire d&rsquo;imagination et de cr\u00e9ativit\u00e9 Enjoy !<\/p>\n<p>&nbsp;<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Cet article pr\u00e9sente comment superviser des JVMs gr\u00e2ce \u00e0 la solution open-source Prometheus. Ce produit s&rsquo;apparente \u00e0 une solution de supervision et d&rsquo;alerte des composants r\u00e9guli\u00e8rement rencontr\u00e9s dans un SI : bases de donn\u00e9es, MOM, syst\u00e8mes de fichiers, r\u00e9partiteurs\u00a0 de charge, serveurs d&rsquo;application, serveurs HTTP, etc&#8230; Le produit r\u00e9cup\u00e8res les infos aupr\u00e8s des diff\u00e9rents composants [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_monsterinsights_skip_tracking":false,"_monsterinsights_sitenote_active":false,"_monsterinsights_sitenote_note":"","_monsterinsights_sitenote_category":0,"footnotes":""},"categories":[1],"tags":[],"class_list":["post-205","post","type-post","status-publish","format-standard","hentry","category-non-classe"],"_links":{"self":[{"href":"https:\/\/corsaire-consulting.fr\/blog\/index.php\/wp-json\/wp\/v2\/posts\/205","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/corsaire-consulting.fr\/blog\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/corsaire-consulting.fr\/blog\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/corsaire-consulting.fr\/blog\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/corsaire-consulting.fr\/blog\/index.php\/wp-json\/wp\/v2\/comments?post=205"}],"version-history":[{"count":6,"href":"https:\/\/corsaire-consulting.fr\/blog\/index.php\/wp-json\/wp\/v2\/posts\/205\/revisions"}],"predecessor-version":[{"id":235,"href":"https:\/\/corsaire-consulting.fr\/blog\/index.php\/wp-json\/wp\/v2\/posts\/205\/revisions\/235"}],"wp:attachment":[{"href":"https:\/\/corsaire-consulting.fr\/blog\/index.php\/wp-json\/wp\/v2\/media?parent=205"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/corsaire-consulting.fr\/blog\/index.php\/wp-json\/wp\/v2\/categories?post=205"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/corsaire-consulting.fr\/blog\/index.php\/wp-json\/wp\/v2\/tags?post=205"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}