package org.atomhopper.util; import com.codahale.metrics.*; import com.codahale.metrics.graphite.Graphite; import com.codahale.metrics.graphite.GraphiteReporter; import org.apache.tomcat.jdbc.pool.DataSource; import org.apache.tomcat.jdbc.pool.jmx.ConnectionPool; import javax.management.*; import java.lang.management.ManagementFactory; import java.net.InetSocketAddress; import java.sql.SQLException; import java.util.Map; import java.util.concurrent.TimeUnit; import static com.codahale.metrics.MetricRegistry.*; /** * This class takes a map of org.apache.tomcat.jdbc.pool.DataSource beans, and the contact information to a graphite * server. The bean will register the MBeans with the JVM, the MetricRegistry & send the data to the graphite server. * * .count is added to each attribute name to force graphite to report the actual value as opposed to an average. * * @param map Map<String, DataSource> - The key is the OName to register the MBean under (e.g., * ConnectionPools:name=demo-jdbc-new-feed-read-repository-bean) and the corresponding DataSource object * @param host String - the graphite server hostname * @param port int - the graphite server port * @param period int - the period in seconds between data reported to the graphite server * @param prefix String - the prefix for the MBeans in the graphite server * */ public class TomcatJdbcPoolGraphiteReporter { public TomcatJdbcPoolGraphiteReporter( Map<String, DataSource> map, String host, int port, int period, String prefix ) throws MalformedObjectNameException, SQLException, NotCompliantMBeanException, InstanceAlreadyExistsException, MBeanRegistrationException, InstanceNotFoundException { synchronized ( this ) { MetricRegistry registry = new MetricRegistry(); MBeanServer server = ManagementFactory.getPlatformMBeanServer(); // register with Metrics for( String name : map.keySet() ) { ObjectName oName = new ObjectName( name ); if( server.isRegistered( oName ) ) { server.unregisterMBean( oName ); } ConnectionPool pool = map.get( name ).createPool().getJmxPool(); server.registerMBean( pool, oName ); registry.register( name( oName.getKeyProperty( "name" ), "NumActive.count" ), new JmxAttributeGauge( oName, "NumActive" ) ); registry.register( name( oName.getKeyProperty( "name" ), "NumIdle.count" ), new JmxAttributeGauge( oName, "NumIdle" ) ); registry.register( name( oName.getKeyProperty( "name" ), "Size.count" ), new JmxAttributeGauge( oName, "Size" ) ); } Graphite graphite = new Graphite( new InetSocketAddress( host, port) ); final GraphiteReporter reporter = GraphiteReporter.forRegistry( registry ) .prefixedWith( prefix ) .convertRatesTo( TimeUnit.SECONDS ) .convertDurationsTo( TimeUnit.MILLISECONDS ) .filter( MetricFilter.ALL ) .build( graphite ); reporter.start( period, TimeUnit.SECONDS ); Runtime.getRuntime().addShutdownHook( new Thread() { public void run() { reporter.stop(); } }); } } }