To monitor Apache Tomcat, the most convenient solution is to use JMX Exporter provided by Prometheus git repository.

Enable JMX Remote

To enable JMX Remote, I will simply add the following line into setenv.sh file (file store in /bin of Apache Tomcat installation directory):

export CATALINA_OPTS="-Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.port=9999 -Dcom.sun.management.jmxremote.ssl=false -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.host=127.0.1.1"

As a check, after the restart of the service, I look for listening port 9999:

[root@srv-linux-1 ~]# netstat -lnp | grep 9999
tcp        0      0 127.0.1.1:9999          0.0.0.0:*               LISTEN      109763/java

I intentionally limited the listen address to local address for security reason.

JMX Exporter

To start, I need to download the agent. For version 0.18.0, I am downloading it from https://repo1.maven.org/maven2/io/prometheus/jmx/jmx_prometheus_httpserver/0.18.0/jmx_prometheus_httpserver-0.18.0.jar.

Then, I create the config.yaml file:

hostPort: 127.0.1.1:9999
rules:
- pattern: ".*"

As there is no pattern rules (or a bypass), all metrics will be exported which will add load to the server. In my case, I have more than 560 metrics.

I am ready to start the exporter. First parameters is the listening port. Second is the config file to use:

java -jar jmx_prometheus_httpserver-0.18.0.jar 12345 config.yaml

Then, I can access the exporter URL http://192.168.33.10:12345/:

# HELP jmx_config_reload_success_total Number of times configuration have successfully been reloaded.
# TYPE jmx_config_reload_success_total counter
jmx_config_reload_success_total 0.0
# HELP jmx_exporter_build_info A metric with a constant '1' value labeled with the version of the JMX exporter.
# TYPE jmx_exporter_build_info gauge
jmx_exporter_build_info{version="0.18.0",name="jmx_prometheus_httpserver",} 1.0
# HELP jmx_config_reload_failure_total Number of times configuration have failed to be reloaded.
# TYPE jmx_config_reload_failure_total counter
jmx_config_reload_failure_total 0.0
...

Result includes request duration:

# TYPE jmx_scrape_duration_seconds gauge
jmx_scrape_duration_seconds 0.357443022

It is quite long duration for a monitoring task, so we must consider changing filtering pattern. Github repository includes an example of config file for tomcat. It also renames metrics:

# HELP tomcat_servlet_requestcount_total Tomcat servlet requestCount total
# TYPE tomcat_servlet_requestcount_total counter
tomcat_servlet_requestcount_total{module="localhost/helloworld",servlet="jsp",} 46638.0
tomcat_servlet_requestcount_total{module="localhost/helloworld",servlet="default",} 0.0
# HELP tomcat_serverinfo_total Tomcat server release identifier Catalina:name=null,type=Server,attribute=serverInfo
# TYPE tomcat_serverinfo_total counter
tomcat_serverinfo{serverinfo="Server_0",} 1.0
# HELP tomcat_session_sessioncounter_total Tomcat session sessionCounter total
# TYPE tomcat_session_sessioncounter_total counter
tomcat_session_sessioncounter_total{context="/helloworld",host="localhost",} 46632.0
# HELP tomcat_session_rejectedsessions_total Tomcat session rejectedSessions total
# TYPE tomcat_session_rejectedsessions_total counter
tomcat_session_rejectedsessions_total{context="/helloworld",host="localhost",} 0.0
# HELP tomcat_session_expiredsessions_total Tomcat session expiredSessions total
# TYPE tomcat_session_expiredsessions_total counter
tomcat_session_expiredsessions_total{context="/helloworld",host="localhost",} 46050.0
# HELP tomcat_session_processingtime_total Tomcat session processingTime total
# TYPE tomcat_session_processingtime_total counter
tomcat_session_processingtime_total{context="/helloworld",host="localhost",} 354.0
# HELP tomcat_servlet_processingtime_total Tomcat servlet processingTime total
# TYPE tomcat_servlet_processingtime_total counter
tomcat_servlet_processingtime_total{module="localhost/helloworld",servlet="jsp",} 75470.0
tomcat_servlet_processingtime_total{module="localhost/helloworld",servlet="default",} 0.0
# HELP tomcat_servlet_errorcount_total Tomcat servlet errorCount total
# TYPE tomcat_servlet_errorcount_total counter
tomcat_servlet_errorcount_total{module="localhost/helloworld",servlet="jsp",} 0.0
tomcat_servlet_errorcount_total{module="localhost/helloworld",servlet="default",} 0.0
# HELP jmx_scrape_duration_seconds Time this JMX scrape took, in seconds.
# TYPE jmx_scrape_duration_seconds gauge
jmx_scrape_duration_seconds 1.470627824
# HELP jmx_scrape_error Non-zero if this scrape failed.
# TYPE jmx_scrape_error gauge
jmx_scrape_error 0.0
# HELP jmx_scrape_cached_beans Number of beans with their matching rule cached
# TYPE jmx_scrape_cached_beans gauge
jmx_scrape_cached_beans 0.0
# HELP jmx_config_reload_success_total Number of times configuration have successfully been reloaded.
# TYPE jmx_config_reload_success_total counter
jmx_config_reload_success_total 0.0
# HELP jmx_exporter_build_info A metric with a constant '1' value labeled with the version of the JMX exporter.
# TYPE jmx_exporter_build_info gauge
jmx_exporter_build_info{version="0.18.0",name="jmx_prometheus_httpserver",} 1.0
# HELP jmx_config_reload_failure_total Number of times configuration have failed to be reloaded.
# TYPE jmx_config_reload_failure_total counter
jmx_config_reload_failure_total 0.0
# HELP jmx_config_reload_failure_created Number of times configuration have failed to be reloaded.
# TYPE jmx_config_reload_failure_created gauge
jmx_config_reload_failure_created 1.679932831626E9
# HELP jmx_config_reload_success_created Number of times configuration have successfully been reloaded.
# TYPE jmx_config_reload_success_created gauge
jmx_config_reload_success_created 1.679932831621E9

Now, only Grafana dashboard remains.