001package nl.nlighten.prometheus.tomcat; 002 003import io.prometheus.client.Collector; 004import io.prometheus.client.GaugeMetricFamily; 005 006import javax.management.MBeanServer; 007import javax.management.ObjectInstance; 008import javax.management.ObjectName; 009import java.lang.management.ManagementFactory; 010import java.util.*; 011 012/** 013 * Exports Tomcat <a href="http://tomcat.apache.org/tomcat-8.5-doc/jdbc-pool.html">jdbc-pool</a> metrics. 014 * <p> 015 * Example usage: 016 * <pre> 017 * {@code 018 * new TomcatJdbcPoolExports().register(); 019 * } 020 * </pre> 021 * Example metrics being exported: 022 * <pre> 023 * tomcat_jdbc_connections_max{pool="jdbc/mypool"} 20.0 024 * tomcat_jdbc_connections_active_total{pool="jdbc/mypool"} 2.0 025 * tomcat_jdbc_connections_idle_total{pool="jdbc/mypool"} 6.0 026 * tomcat_jdbc_connections_total{pool="jdbc/mypool"} 8.0 027 * tomcat_jdbc_connections_threadswaiting_total{pool="jdbc/mypool"} 0.0 028 * </pre> 029 */ 030 031public class TomcatJdbcPoolExports extends Collector { 032 033 public List<MetricFamilySamples> collect() { 034 List<MetricFamilySamples> mfs = new ArrayList<MetricFamilySamples>(); 035 try { 036 final MBeanServer server = ManagementFactory.getPlatformMBeanServer(); 037 ObjectName filterName = new ObjectName("tomcat.jdbc:class=org.apache.tomcat.jdbc.pool.DataSource,type=ConnectionPool,*"); 038 Set<ObjectInstance> mBeans = server.queryMBeans(filterName, null); 039 040 if (mBeans.size() > 0) { 041 List<String> labelList = Collections.singletonList("pool"); 042 043 GaugeMetricFamily maxActiveConnectionsGauge = new GaugeMetricFamily( 044 "tomcat_jdbc_connections_max", 045 "Maximum number of active connections that can be allocated from this pool at the same time", 046 labelList); 047 048 GaugeMetricFamily activeConnectionsGauge = new GaugeMetricFamily( 049 "tomcat_jdbc_connections_active_total", 050 "Number of active connections allocated from this pool", 051 labelList); 052 053 GaugeMetricFamily idleConnectionsGauge = new GaugeMetricFamily( 054 "tomcat_jdbc_connections_idle_total", 055 "Number of idle connections in this pool", 056 labelList); 057 058 GaugeMetricFamily totalConnectionsGauge = new GaugeMetricFamily( 059 "tomcat_jdbc_connections_total", 060 "Total number of connections in this pool", 061 labelList); 062 063 GaugeMetricFamily waitingThreadsCountGauge = new GaugeMetricFamily( 064 "tomcat_jdbc_waitingthreads_total", 065 "Number of threads waiting for connections from this pool", 066 labelList); 067 068 for (final ObjectInstance mBean : mBeans) { 069 List<String> labelValueList = Collections.singletonList(mBean.getObjectName().getKeyProperty("name").replaceAll("[\"\\\\]", "")); 070 071 maxActiveConnectionsGauge.addMetric( 072 labelValueList, 073 ((Integer) server.getAttribute(mBean.getObjectName(), "MaxActive")).doubleValue()); 074 075 activeConnectionsGauge.addMetric( 076 labelValueList, 077 ((Integer) server.getAttribute(mBean.getObjectName(), "Active")).doubleValue()); 078 079 idleConnectionsGauge.addMetric( 080 labelValueList, 081 ((Integer) server.getAttribute(mBean.getObjectName(), "Idle")).doubleValue()); 082 083 totalConnectionsGauge.addMetric( 084 labelValueList, 085 ((Integer) server.getAttribute(mBean.getObjectName(), "Size")).doubleValue()); 086 087 waitingThreadsCountGauge.addMetric( 088 labelValueList, 089 ((Integer) server.getAttribute(mBean.getObjectName(), "WaitCount")).doubleValue()); 090 } 091 092 mfs.add(maxActiveConnectionsGauge); 093 mfs.add(activeConnectionsGauge); 094 mfs.add(idleConnectionsGauge); 095 mfs.add(totalConnectionsGauge); 096 mfs.add(waitingThreadsCountGauge); 097 } 098 } catch (Exception e) { 099 e.printStackTrace(); 100 } 101 return mfs; 102 } 103 104 public static boolean isTomcatJdbcUsed() { 105 try { 106 final MBeanServer server = ManagementFactory.getPlatformMBeanServer(); 107 ObjectName filterName = new ObjectName("tomcat.jdbc:class=org.apache.tomcat.jdbc.pool.DataSource,type=ConnectionPool,*"); 108 Set<ObjectInstance> mBeans = server.queryMBeans(filterName, null); 109 return !mBeans.isEmpty(); 110 } catch (Exception e) { 111 e.printStackTrace(); 112 } 113 return false; 114 } 115 116}