001package nl.nlighten.prometheus.wildfly; 002 003import io.prometheus.client.Collector; 004import io.prometheus.client.CounterMetricFamily; 005import io.prometheus.client.GaugeMetricFamily; 006 007import javax.management.MBeanServer; 008import javax.management.ObjectInstance; 009import javax.management.ObjectName; 010import java.lang.management.ManagementFactory; 011import java.util.ArrayList; 012import java.util.Collections; 013import java.util.List; 014import java.util.Set; 015 016/** 017 * Exports metrics about Jboss Wildfly JDBC datasources. 018 * <p> 019 * Example usage: 020 * <pre> 021 * {@code 022 * new JbossJdbcPoolExports().register(); 023 * } 024 * </pre> 025 * Example metrics being exported: 026 * <pre> 027 * jboss_jdbc_connections_total{pool="ExampleDS",} 10.0 028 * jboss_jdbc_connections_threadswaiting_total{pool="ExampleDS",} 0.0 029 * jboss_jdbc_connections_idle_total{pool="ExampleDS",} 8.0 030 * jboss_jdbc_connections_active_total{pool="ExampleDS",} 2.0 031 * jboss_jdbc_xacommit_total{pool="ExampleDS",} 9837.0 032 * jboss_jdbc_xarollback_total{pool="ExampleDS",} 7.0 033 * jboss_jdbc_xarecover_total{pool="ExampleDS",} 0.0 034 * jboss_jdbc_preparedstatementcache_size_total{pool="ExampleDS",} 100.0 035 * jboss_jdbc_preparedstatementcache_miss_total{pool="ExampleDS",} 0.0 036 * jboss_jdbc_preparedstatementcache_hit_total{pool="ExampleDS",} 94837.0 037 * </pre> 038 * <p> 039 * Note that you need to enable datasource statistics to see anything 040 */ 041public class JbossJdbcPoolExports extends Collector { 042 043 public List<MetricFamilySamples> collect() { 044 List<MetricFamilySamples> mfs = new ArrayList<>(); 045 try { 046 MBeanServer server = ManagementFactory.getPlatformMBeanServer(); 047 048 // data source stats 049 ObjectName filterName = new ObjectName("jboss.as:subsystem=datasources,data-source=*,statistics=pool"); 050 Set<ObjectInstance> mBeans = server.queryMBeans(filterName, null); 051 if (mBeans.size() > 0) { 052 List<String> labelList = Collections.singletonList("pool"); 053 054 GaugeMetricFamily activeCountGauge = new GaugeMetricFamily( 055 "jboss_jdbc_connections_total", 056 "Total number of connections in this pool", 057 labelList); 058 059 GaugeMetricFamily waitCountGauge = new GaugeMetricFamily( 060 "jboss_jdbc_connections_threadswaiting_total", 061 "Number of threads waiting for connections from this pool", 062 labelList); 063 064 GaugeMetricFamily idleCountGauge = new GaugeMetricFamily( 065 "jboss_jdbc_connections_idle_total", 066 "Number of idle connections in this pool", 067 labelList); 068 069 GaugeMetricFamily inUseCountGauge = new GaugeMetricFamily( 070 "jboss_jdbc_connections_active_total", 071 "Number of connections in use", 072 labelList); 073 074 CounterMetricFamily xaCommitCounter = new CounterMetricFamily( 075 "jboss_jdbc_xacommit_total", 076 "Number of xa commits", 077 labelList); 078 079 CounterMetricFamily xaRollbackCounter = new CounterMetricFamily( 080 "jboss_jdbc_xarollback_total", 081 "Number of xa recoveries", 082 labelList); 083 084 CounterMetricFamily xaRecoverCounter = new CounterMetricFamily( 085 "jboss_jdbc_xarecover_total", 086 "Number of xa recoveries", 087 labelList); 088 089 for (final ObjectInstance mBean : mBeans) { 090 091 activeCountGauge.addMetric( 092 Collections.singletonList(mBean.getObjectName().getKeyProperty("data-source")), 093 ((Integer) server.getAttribute(mBean.getObjectName(), "ActiveCount")).doubleValue()); 094 095 waitCountGauge.addMetric( 096 Collections.singletonList(mBean.getObjectName().getKeyProperty("data-source")), 097 ((Integer) server.getAttribute(mBean.getObjectName(), "WaitCount")).doubleValue()); 098 099 idleCountGauge.addMetric( 100 Collections.singletonList(mBean.getObjectName().getKeyProperty("data-source")), 101 ((Integer) server.getAttribute(mBean.getObjectName(), "IdleCount")).doubleValue()); 102 103 inUseCountGauge.addMetric( 104 Collections.singletonList(mBean.getObjectName().getKeyProperty("data-source")), 105 ((Integer) server.getAttribute(mBean.getObjectName(), "InUseCount")).doubleValue()); 106 107 xaCommitCounter.addMetric( 108 Collections.singletonList(mBean.getObjectName().getKeyProperty("data-source")), 109 ((Long) server.getAttribute(mBean.getObjectName(), "XACommitCount")).doubleValue()); 110 111 xaRollbackCounter.addMetric( 112 Collections.singletonList(mBean.getObjectName().getKeyProperty("data-source")), 113 ((Long) server.getAttribute(mBean.getObjectName(), "XARollbackCount")).doubleValue()); 114 115 xaRecoverCounter.addMetric( 116 Collections.singletonList(mBean.getObjectName().getKeyProperty("data-source")), 117 ((Long) server.getAttribute(mBean.getObjectName(), "XARecoverCount")).doubleValue()); 118 } 119 mfs.add(activeCountGauge); 120 mfs.add(waitCountGauge); 121 mfs.add(inUseCountGauge); 122 mfs.add(xaCommitCounter); 123 mfs.add(xaRollbackCounter); 124 mfs.add(xaRecoverCounter); 125 } 126 127 // jdbc stats 128 filterName = new ObjectName("jboss.as:subsystem=datasources,data-source=*,statistics=jdbc"); 129 mBeans = server.queryMBeans(filterName, null); 130 if (mBeans.size() > 0) { 131 List<String> labelList = Collections.singletonList("pool"); 132 133 GaugeMetricFamily preparedStatementCacheCurrentSizeGauge = new GaugeMetricFamily( 134 "jboss_jdbc_preparedstatementcache_size_total", 135 "Prepared statement cache size", 136 labelList); 137 138 CounterMetricFamily preparedStatementCacheMissCounter = new CounterMetricFamily( 139 "jboss_jdbc_preparedstatementcache_miss_total", 140 "Prepared statement cache miss count", 141 labelList); 142 143 CounterMetricFamily preparedStatementCacheHitCounter = new CounterMetricFamily( 144 "jboss_jdbc_preparedstatementcache_hit_total", 145 "Prepared statement cache hit count", 146 labelList); 147 148 for (final ObjectInstance mBean : mBeans) { 149 preparedStatementCacheCurrentSizeGauge.addMetric( 150 Collections.singletonList(mBean.getObjectName().getKeyProperty("data-source")), 151 ((Integer) server.getAttribute(mBean.getObjectName(), "PreparedStatementCacheCurrentSize")).doubleValue()); 152 153 preparedStatementCacheMissCounter.addMetric( 154 Collections.singletonList(mBean.getObjectName().getKeyProperty("data-source")), 155 ((Long) server.getAttribute(mBean.getObjectName(), "PreparedStatementCacheMissCount")).doubleValue()); 156 157 preparedStatementCacheHitCounter.addMetric( 158 Collections.singletonList(mBean.getObjectName().getKeyProperty("data-source")), 159 ((Long) server.getAttribute(mBean.getObjectName(), "PreparedStatementCacheHitCount")).doubleValue()); 160 161 } 162 mfs.add(preparedStatementCacheCurrentSizeGauge); 163 mfs.add(preparedStatementCacheMissCounter); 164 mfs.add(preparedStatementCacheHitCounter); 165 } 166 167 } catch (Exception e) { 168 e.printStackTrace(); 169 } 170 return mfs; 171 } 172} 173