{"id":836,"date":"2024-06-25T09:39:08","date_gmt":"2024-06-25T09:39:08","guid":{"rendered":"https:\/\/blog.ngocha.biz\/?p=836"},"modified":"2024-06-25T09:39:08","modified_gmt":"2024-06-25T09:39:08","slug":"setup-prometheus-jmx-exporter","status":"publish","type":"post","link":"https:\/\/blog.ngocha.biz\/?p=836","title":{"rendered":"How to Setup Prometheus JMX Exporter on Linux [ Tutorial ]"},"content":{"rendered":"<p>In this blog, you will learn to install and configure <a href=\"https:\/\/devopscube.com\/prometheus-architecture\/\"><strong>Prometheus<\/strong><\/a><strong> JMX Exporter<\/strong> on a Linux server.<\/p>\n<p>You will also learn to instrument a Java application using the JMX Exporter, export metrics to prometheus and query it using PromQL.<\/p>\n<h2 id=\"prerequisites\">Prerequisites<\/h2>\n<p>Here are the prerequisites for setting up a JMX exporter on a Virtual machine.<\/p>\n<p>We need two servers.<\/p>\n<ol>\n<li><strong>Server 01<\/strong>: Prometheus server up and running. If you dont have a Prometheus setup, follow the <a href=\"https:\/\/devopscube.com\/install-configure-prometheus-linux\/\">Prometheus setup on linux<\/a> blog.<\/li>\n<li><strong>Server 02<\/strong>: Server to run the <a href=\"https:\/\/devopscube.com\/build-java-application-using-maven\/\">Java application<\/a> and the JMX exporter.<\/li>\n<\/ol>\n<h2 id=\"how-to-setup-jmx-exporter-on-vm\"><strong>How To Setup JMX Exporter on VM?<\/strong><\/h2>\n<p>For this tutorial, I am using two Ubuntu based EC2 instances and the instance type is t2.medium.<\/p>\n<p>I assume you already have the Java application (jar files), or if you want to test that, you can use this repository.<\/p>\n<pre><code>git clone https:\/\/github.com\/techiescamp\/java-spring-petclinic<\/code><\/pre>\n<p>Follow the steps given below for the setup and configuration.<\/p>\n<h3 id=\"step-1-download-the-jmx-exporter-agent\">Step 1: Download the JMX Exporter Agent<\/h3>\n<p>To download the <strong>JMX Exporter Java agent<\/strong>, use the following command.<\/p>\n<pre><code>wget https:\/\/repo1.maven.org\/maven2\/io\/prometheus\/jmx\/jmx_prometheus_javaagent\/0.19.0\/jmx_prometheus_javaagent-0.19.0.jar<\/code><\/pre>\n<p>The next step is to create a configuration file for the JMX Exporter <code>config.yaml<\/code>. This file will decide what has to be collected from the JMX MBean server.<\/p>\n<h3 id=\"step-2-create-a-configuration-file-for-the-jmx-exporter\">Step 2: Create a Configuration File for the JMX Exporter<\/h3>\n<p>There are a lot of metrics and information available on the MBean server, but we might only have a few metrics to monitor, we provide configuration to filter the necessary metrics from the server.<\/p>\n<p>Create a configuration file <strong>config.yaml<\/strong><\/p>\n<pre><code>lowercaseOutputName: true\nlowercaseOutputLabelNames: true\n\nrules:\n  - pattern: 'java.lang:type=Memory'<\/code><\/pre>\n<p>For testing purposes, I am using this configuration to filter the memory-related metrics. For all the supported metrics, please refer to the <a href=\"https:\/\/github.com\/prometheus\/jmx_exporter?ref=devopscube.com\">official documentation<\/a>.<\/p>\n<h3 id=\"step-3-expose-metrics-through-the-http-server\">Step 3: Expose Metrics through the HTTP Server<\/h3>\n<p>To expose the Java application metrics, use the following command.<\/p>\n<pre><code>sudo java -javaagent:jmx_prometheus_javaagent-0.19.0.jar=9093:config.yaml -jar java-spring-petclinic\/target\/spring-petclinic-3.2.0-SNAPSHOT.jar<\/code><\/pre>\n<p>The JMX Exporter will be used as a <strong>Java application&#8217;s runtime agent<\/strong> and I have given the port number <code>9093<\/code>, you can give a different one because there is no default port for the JMX Exporter.<\/p>\n<p>To view the metrics from the localhost, use the following command.<\/p>\n<pre><code>curl localhost:9093<\/code><\/pre>\n<p>If you want to see the metrics over the internet then you need the instance public IP and the Port number.<\/p>\n<p>Open a browser and paste the <strong>Public IP<\/strong> and the port number <strong>&lt;Public IP&gt;:9093<\/strong>, and you will get this output.<\/p>\n<figure class=\"kg-card kg-image-card\"><img decoding=\"async\" src=\"https:\/\/storage.ghost.io\/c\/5f\/2f\/5f2f4d20-2abf-4534-8d40-7aa233aedd43\/content\/images\/2025\/03\/image-91-6.png\" class=\"kg-image\" alt=\"prometheus jmx exporter metrics\" loading=\"lazy\" width=\"1229\" height=\"1015\" srcset=\"https:\/\/storage.ghost.io\/c\/5f\/2f\/5f2f4d20-2abf-4534-8d40-7aa233aedd43\/content\/images\/size\/w600\/2025\/03\/image-91-6.png 600w, https:\/\/storage.ghost.io\/c\/5f\/2f\/5f2f4d20-2abf-4534-8d40-7aa233aedd43\/content\/images\/size\/w1000\/2025\/03\/image-91-6.png 1000w, https:\/\/storage.ghost.io\/c\/5f\/2f\/5f2f4d20-2abf-4534-8d40-7aa233aedd43\/content\/images\/2025\/03\/image-91-6.png 1229w\" sizes=\"auto, (min-width: 720px) 720px\"><\/figure>\n<p>Now we can check <strong>Prometheus<\/strong> and ensure that it is periodically scrapping the metrics from the <strong>JMX Exporter.<\/strong><\/p>\n<h3 id=\"step-4-add-jmx-exporter-job-in-prometheus\">Step 4: Add JMX Exporter Job in Prometheus<\/h3>\n<p>We need to create a job in the Prometheus configuration file then only Prometheus can pull and store the metrics in the <strong>Time Series Database.<\/strong><\/p>\n<p>If you haven&#8217;t installed Prometheus on the cluster, refer to this <a href=\"https:\/\/devopscube.com\/install-configure-prometheus-linux\/\">blog<\/a>.<\/p>\n<p>Open the configuration file <code>\/etc\/prometheus\/prometheus.yaml<\/code><\/p>\n<pre><code>sudo vim \/etc\/prometheus\/prometheus.yml<\/code><\/pre>\n<p>Under the <code>scrape_configs<\/code> add a new job<\/p>\n<pre><code>- job_name: \"jmx-exporter\"\n    static_configs:\n    - targets: [\"&lt;Public_IP&gt;:9093\"]<\/code><\/pre>\n<p>Provide the <strong>Public IP<\/strong> address of the server where your JMX Exporter is and the Port number of the JMX Exporter <code>9093<\/code>.<\/p>\n<p>Once the configuration is completed, restart the Prometheus service and view the status to ensure the configurations are properly applied.<\/p>\n<pre><code>sudo systemctl restart prometheus.service\nsudo systemctl status prometheus.service<\/code><\/pre>\n<p>First, we will list the Prometheus targets.<\/p>\n<figure class=\"kg-card kg-image-card\"><img decoding=\"async\" src=\"https:\/\/storage.ghost.io\/c\/5f\/2f\/5f2f4d20-2abf-4534-8d40-7aa233aedd43\/content\/images\/2025\/03\/image-92-6.png\" class=\"kg-image\" alt=\"Prometheus dashboard with JMX target\" loading=\"lazy\" width=\"795\" height=\"445\" srcset=\"https:\/\/storage.ghost.io\/c\/5f\/2f\/5f2f4d20-2abf-4534-8d40-7aa233aedd43\/content\/images\/size\/w600\/2025\/03\/image-92-6.png 600w, https:\/\/storage.ghost.io\/c\/5f\/2f\/5f2f4d20-2abf-4534-8d40-7aa233aedd43\/content\/images\/2025\/03\/image-92-6.png 795w\" sizes=\"auto, (min-width: 720px) 720px\"><\/figure>\n<p>This ensures that the Prometheus can access the <strong>JMX Exporter endpoint<\/strong> and the state of the Exporter.<\/p>\n<p>Let&#8217;s make a query from the Prometheus and see the results.<\/p>\n<figure class=\"kg-card kg-image-card\"><img decoding=\"async\" src=\"https:\/\/storage.ghost.io\/c\/5f\/2f\/5f2f4d20-2abf-4534-8d40-7aa233aedd43\/content\/images\/2025\/03\/image-94-5.png\" class=\"kg-image\" alt=\"prometheus query to filter JMX metrics\" loading=\"lazy\" width=\"787\" height=\"448\" srcset=\"https:\/\/storage.ghost.io\/c\/5f\/2f\/5f2f4d20-2abf-4534-8d40-7aa233aedd43\/content\/images\/size\/w600\/2025\/03\/image-94-5.png 600w, https:\/\/storage.ghost.io\/c\/5f\/2f\/5f2f4d20-2abf-4534-8d40-7aa233aedd43\/content\/images\/2025\/03\/image-94-5.png 787w\" sizes=\"auto, (min-width: 720px) 720px\"><\/figure>\n<p>We can see the visual representation for our query result, using the <strong>Grafana.<\/strong><\/p>\n<p>To install Grafana on your Virtual Machine, refer to this <a href=\"https:\/\/devopscube.com\/integrate-visualize-prometheus-grafana\/\">blog<\/a>.<\/p>\n<figure class=\"kg-card kg-image-card\"><img decoding=\"async\" src=\"https:\/\/storage.ghost.io\/c\/5f\/2f\/5f2f4d20-2abf-4534-8d40-7aa233aedd43\/content\/images\/2025\/03\/image-98-3.png\" class=\"kg-image\" alt=\"grafana jmx exporter dashboard\" loading=\"lazy\" width=\"1108\" height=\"909\" srcset=\"https:\/\/storage.ghost.io\/c\/5f\/2f\/5f2f4d20-2abf-4534-8d40-7aa233aedd43\/content\/images\/size\/w600\/2025\/03\/image-98-3.png 600w, https:\/\/storage.ghost.io\/c\/5f\/2f\/5f2f4d20-2abf-4534-8d40-7aa233aedd43\/content\/images\/size\/w1000\/2025\/03\/image-98-3.png 1000w, https:\/\/storage.ghost.io\/c\/5f\/2f\/5f2f4d20-2abf-4534-8d40-7aa233aedd43\/content\/images\/2025\/03\/image-98-3.png 1108w\" sizes=\"auto, (min-width: 720px) 720px\"><\/figure>\n<h2 id=\"conclusion\"><strong>Conclusion<\/strong><\/h2>\n<p>I have covered all the steps to instrument a Java application using Prometheus JMX exporter and run on a Linux server.<\/p>\n<p>If you are using Kubernetes, you can try implement the <a href=\"https:\/\/devopscube.com\/prometheus-jmx-exporter-on-kubernetes\/\">JMX Exporter in the Kubernetes cluste<\/a>r to monitor the Java application running in <a href=\"https:\/\/devopscube.com\/kubernetes-pod\/\">Kubernetes Pod<\/a> .<\/p>\n<p>If you face any issues or need clarification on the setup, please drop a comment below. I will help you out.<\/p>\n<hr>\n<p><strong>Ngu\u1ed3n:<\/strong> <a href=\"https:\/\/devopscube.com\/setup-prometheus-jmx-exporter\/\" target=\"_blank\" rel=\"noopener noreferrer\">How to Setup Prometheus JMX Exporter on Linux [ Tutorial ] \u2014 DevOpsCube<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Source: https:\/\/devopscube.com\/setup-prometheus-jmx-exporter\/<\/p>\n","protected":false},"author":1,"featured_media":837,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1],"tags":[],"class_list":["post-836","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-devops"],"_links":{"self":[{"href":"https:\/\/blog.ngocha.biz\/index.php?rest_route=\/wp\/v2\/posts\/836","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/blog.ngocha.biz\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blog.ngocha.biz\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blog.ngocha.biz\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/blog.ngocha.biz\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=836"}],"version-history":[{"count":0,"href":"https:\/\/blog.ngocha.biz\/index.php?rest_route=\/wp\/v2\/posts\/836\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/blog.ngocha.biz\/index.php?rest_route=\/wp\/v2\/media\/837"}],"wp:attachment":[{"href":"https:\/\/blog.ngocha.biz\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=836"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.ngocha.biz\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=836"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.ngocha.biz\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=836"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}