You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tomcat.apache.org by fh...@apache.org on 2009/04/15 06:58:06 UTC
svn commit: r765051 - in
/tomcat/trunk/modules/jdbc-pool/java/org/apache/tomcat/jdbc/pool: ./
interceptor/ jmx/
Author: fhanik
Date: Wed Apr 15 04:58:06 2009
New Revision: 765051
URL: http://svn.apache.org/viewvc?rev=765051&view=rev
Log:
JMX needs to be handled a bit differently. Random object names are not all that great.
In this way, one can control the JMX registration completely from the outside.
Modified:
tomcat/trunk/modules/jdbc-pool/java/org/apache/tomcat/jdbc/pool/ConnectionPool.java
tomcat/trunk/modules/jdbc-pool/java/org/apache/tomcat/jdbc/pool/DataSource.java
tomcat/trunk/modules/jdbc-pool/java/org/apache/tomcat/jdbc/pool/DataSourceProxy.java
tomcat/trunk/modules/jdbc-pool/java/org/apache/tomcat/jdbc/pool/interceptor/SlowQueryReportJmx.java
tomcat/trunk/modules/jdbc-pool/java/org/apache/tomcat/jdbc/pool/jmx/ConnectionPool.java
tomcat/trunk/modules/jdbc-pool/java/org/apache/tomcat/jdbc/pool/jmx/ConnectionPoolMBean.java
tomcat/trunk/modules/jdbc-pool/java/org/apache/tomcat/jdbc/pool/mbeans-descriptors.xml
Modified: tomcat/trunk/modules/jdbc-pool/java/org/apache/tomcat/jdbc/pool/ConnectionPool.java
URL: http://svn.apache.org/viewvc/tomcat/trunk/modules/jdbc-pool/java/org/apache/tomcat/jdbc/pool/ConnectionPool.java?rev=765051&r1=765050&r2=765051&view=diff
==============================================================================
--- tomcat/trunk/modules/jdbc-pool/java/org/apache/tomcat/jdbc/pool/ConnectionPool.java (original)
+++ tomcat/trunk/modules/jdbc-pool/java/org/apache/tomcat/jdbc/pool/ConnectionPool.java Wed Apr 15 04:58:06 2009
@@ -779,17 +779,18 @@
protected void finalize(PooledConnection con) {
}
+
+ public org.apache.tomcat.jdbc.pool.jmx.ConnectionPool getJmxPool() {
+ return jmxPool;
+ }
protected void startJmx() {
try {
- MBeanServer mbs = ManagementFactory.getPlatformMBeanServer();
- ObjectName name = new ObjectName(POOL_JMX_TYPE_PREFIX+"ConnectionPool,name="+getName());
if ("1.5".equals(System.getProperty("java.specification.version"))) {
jmxPool = new org.apache.tomcat.jdbc.pool.jmx.ConnectionPool(this);
} else {
jmxPool = new org.apache.tomcat.jdbc.pool.jmx.ConnectionPool(this,true);
}
- mbs.registerMBean(jmxPool, name);
} catch (Exception x) {
log.warn("Unable to start JMX integration for connection pool. Instance["+getName()+"] can't be monitored.",x);
}
@@ -797,10 +798,6 @@
protected void stopJmx() {
try {
- MBeanServer mbs = ManagementFactory.getPlatformMBeanServer();
- ObjectName name = new ObjectName(POOL_JMX_TYPE_PREFIX+"ConnectionPool,name="+getName());
- if (mbs.isRegistered(name))
- mbs.unregisterMBean(name);
jmxPool = null;
}catch (Exception x) {
log.warn("Unable to stop JMX integration for connection pool. Instance["+getName()+"].",x);
Modified: tomcat/trunk/modules/jdbc-pool/java/org/apache/tomcat/jdbc/pool/DataSource.java
URL: http://svn.apache.org/viewvc/tomcat/trunk/modules/jdbc-pool/java/org/apache/tomcat/jdbc/pool/DataSource.java?rev=765051&r1=765050&r2=765051&view=diff
==============================================================================
--- tomcat/trunk/modules/jdbc-pool/java/org/apache/tomcat/jdbc/pool/DataSource.java (original)
+++ tomcat/trunk/modules/jdbc-pool/java/org/apache/tomcat/jdbc/pool/DataSource.java Wed Apr 15 04:58:06 2009
@@ -16,9 +16,19 @@
*/
package org.apache.tomcat.jdbc.pool;
+import java.lang.management.ManagementFactory;
import java.sql.SQLException;
+import java.util.Hashtable;
import java.util.Properties;
+import javax.management.InstanceNotFoundException;
+import javax.management.MBeanRegistration;
+import javax.management.MBeanServer;
+import javax.management.MalformedObjectNameException;
+import javax.management.ObjectName;
+
+import org.apache.tomcat.jdbc.pool.jmx.ConnectionPoolMBean;
+
/**
* A DataSource that can be instantiated through IoC and implements the DataSource interface
@@ -26,7 +36,7 @@
* @author Filip Hanik
* @version 1.0
*/
-public class DataSource extends DataSourceProxy implements javax.sql.DataSource, org.apache.tomcat.jdbc.pool.jmx.ConnectionPoolMBean {
+public class DataSource extends DataSourceProxy implements MBeanRegistration,javax.sql.DataSource, org.apache.tomcat.jdbc.pool.jmx.ConnectionPoolMBean {
public DataSource() {
super();
@@ -37,6 +47,63 @@
}
//===============================================================================
+// Register the actual pool itself under the tomcat.jdbc domain
+//===============================================================================
+ protected volatile ObjectName oname = null;
+ public void postDeregister() {
+ if (oname!=null) unregisterJmx();
+ }
+
+ public void postRegister(Boolean registrationDone) {
+ }
+
+
+ public void preDeregister() throws Exception {
+ }
+
+ public ObjectName preRegister(MBeanServer server, ObjectName name) throws Exception {
+ try {
+ this.oname = createObjectName(name);
+ if (oname!=null) registerJmx();
+ }catch (MalformedObjectNameException x) {
+ log.error("Unable to create object name for JDBC pool.",x);
+ }
+ return name;
+ }
+
+ public ObjectName createObjectName(ObjectName original) throws MalformedObjectNameException {
+ String domain = "tomcat.jdbc";
+ Hashtable<String,String> properties = original.getKeyPropertyList();
+ String origDomain = original.getDomain();
+ properties.put("type", "ConnectionPool");
+ properties.put("class", this.getClass().getName());
+ if (original.getKeyProperty("path")!=null) {
+ properties.put("engine", origDomain);
+ }
+ ObjectName name = new ObjectName(domain,properties);
+ return name;
+ }
+
+ protected void registerJmx() {
+ try {
+ MBeanServer mbs = ManagementFactory.getPlatformMBeanServer();
+ mbs.registerMBean(pool.getJmxPool(), oname);
+ } catch (Exception e) {
+ log.error("Unable to register JDBC pool with JMX",e);
+ }
+ }
+
+ protected void unregisterJmx() {
+ try {
+ MBeanServer mbs = ManagementFactory.getPlatformMBeanServer();
+ mbs.unregisterMBean(oname);
+ } catch (InstanceNotFoundException ignore) {
+ } catch (Exception e) {
+ log.error("Unable to unregister JDBC pool with JMX",e);
+ }
+ }
+
+//===============================================================================
// Expose JMX attributes through Tomcat's dynamic reflection
//===============================================================================
public void checkAbandoned() {
@@ -62,6 +129,10 @@
throw new RuntimeException(x);
}
}
+
+ public int getNumActive() {
+ return getActive();
+ }
public String getConnectionProperties() {
try {
@@ -110,6 +181,10 @@
throw new RuntimeException(x);
}
}
+
+ public int getNumIdle() {
+ return getIdle();
+ }
public int getInitialSize() {
try {
Modified: tomcat/trunk/modules/jdbc-pool/java/org/apache/tomcat/jdbc/pool/DataSourceProxy.java
URL: http://svn.apache.org/viewvc/tomcat/trunk/modules/jdbc-pool/java/org/apache/tomcat/jdbc/pool/DataSourceProxy.java?rev=765051&r1=765050&r2=765051&view=diff
==============================================================================
--- tomcat/trunk/modules/jdbc-pool/java/org/apache/tomcat/jdbc/pool/DataSourceProxy.java (original)
+++ tomcat/trunk/modules/jdbc-pool/java/org/apache/tomcat/jdbc/pool/DataSourceProxy.java Wed Apr 15 04:58:06 2009
@@ -176,7 +176,9 @@
if (pool != null) {
final ConnectionPool p = pool;
pool = null;
- if (p!=null) p.close(all);
+ if (p!=null) {
+ p.close(all);
+ }
}
}catch (Exception x) {
log.warn("Error duing connection pool closure.", x);
@@ -197,7 +199,7 @@
public String toString() {
return super.toString()+"{"+getPoolProperties()+"}";
}
-
+
/*-----------------------------------------------------------------------*/
// PROPERTIES WHEN NOT USED WITH FACTORY
/*------------------------------------------------------------------------*/
Modified: tomcat/trunk/modules/jdbc-pool/java/org/apache/tomcat/jdbc/pool/interceptor/SlowQueryReportJmx.java
URL: http://svn.apache.org/viewvc/tomcat/trunk/modules/jdbc-pool/java/org/apache/tomcat/jdbc/pool/interceptor/SlowQueryReportJmx.java?rev=765051&r1=765050&r2=765051&view=diff
==============================================================================
--- tomcat/trunk/modules/jdbc-pool/java/org/apache/tomcat/jdbc/pool/interceptor/SlowQueryReportJmx.java (original)
+++ tomcat/trunk/modules/jdbc-pool/java/org/apache/tomcat/jdbc/pool/interceptor/SlowQueryReportJmx.java Wed Apr 15 04:58:06 2009
@@ -50,8 +50,8 @@
*
*/
public class SlowQueryReportJmx extends SlowQueryReport {
- public static final String SLOW_QUERY_NOTIFICATION = "Slow query";
- public static final String FAILED_QUERY_NOTIFICATION = "Failed query";
+ public static final String SLOW_QUERY_NOTIFICATION = "SLOW QUERY";
+ public static final String FAILED_QUERY_NOTIFICATION = "FAILED QUERY";
protected static CompositeType SLOW_QUERY_TYPE;
@@ -65,6 +65,10 @@
protected static AtomicLong notifySequence = new AtomicLong(0);
+ protected boolean notifyPool = true;
+
+ protected ConnectionPool pool = null;
+
protected static CompositeType getCompositeType() {
if (SLOW_QUERY_TYPE==null) {
try {
@@ -85,7 +89,10 @@
public void reset(ConnectionPool parent, PooledConnection con) {
// TODO Auto-generated method stub
super.reset(parent, con);
- if (parent!=null) poolName = parent.getName();
+ if (parent!=null) {
+ poolName = parent.getName();
+ pool = parent;
+ }
}
@@ -99,6 +106,7 @@
@Override
public void poolStarted(ConnectionPool pool) {
+ this.pool = pool;
super.poolStarted(pool);
this.poolName = pool.getName();
registerJmx();
@@ -114,16 +122,23 @@
protected void notifyJmx(String query, String type) {
try {
DynamicMBean mbean = mbeans.get(poolName);
- if (mbean!=null && mbean instanceof BaseModelMBean) {
- BaseModelMBean bmbean = (BaseModelMBean)mbean;
- long sequence = notifySequence.incrementAndGet();
- Notification notification =
- new Notification(type,
- mbean,
- sequence,
- System.currentTimeMillis(),
- query);
- bmbean.sendNotification(notification);
+ long sequence = notifySequence.incrementAndGet();
+
+ if (isNotifyPool()) {
+ if (this.pool!=null && this.pool.getJmxPool()!=null) {
+ this.pool.getJmxPool().notify(type, query);
+ }
+ } else {
+ if (mbean!=null && mbean instanceof BaseModelMBean) {
+ Notification notification =
+ new Notification(type,
+ mbean,
+ sequence,
+ System.currentTimeMillis(),
+ query);
+ BaseModelMBean bmbean = (BaseModelMBean)mbean;
+ bmbean.sendNotification(notification);
+ }
}
} catch (RuntimeOperationsException e) {
if (log.isDebugEnabled()) {
@@ -160,6 +175,16 @@
return poolName;
}
+
+
+ public boolean isNotifyPool() {
+ return notifyPool;
+ }
+
+ public void setNotifyPool(boolean notifyPool) {
+ this.notifyPool = notifyPool;
+ }
+
/**
* JMX operation - remove all stats for this connection pool
*/
@@ -205,7 +230,6 @@
registry.unregisterComponent(oname);
registry.removeManagedBean(managed);
}
-
}
} catch (MalformedObjectNameException e) {
log.warn("Jmx deregistration failed.",e);
@@ -217,7 +241,10 @@
protected void registerJmx() {
try {
- if (getCompositeType()!=null) {
+ //only if we notify the pool itself
+ if (isNotifyPool()) {
+
+ } else if (getCompositeType()!=null) {
ObjectName oname = new ObjectName(ConnectionPool.POOL_JMX_TYPE_PREFIX+"SlowQueryReport"+",name=" + poolName);
Registry registry = Registry.getRegistry(null, null);
registry.loadDescriptors(getClass().getPackage().getName(),getClass().getClassLoader());
Modified: tomcat/trunk/modules/jdbc-pool/java/org/apache/tomcat/jdbc/pool/jmx/ConnectionPool.java
URL: http://svn.apache.org/viewvc/tomcat/trunk/modules/jdbc-pool/java/org/apache/tomcat/jdbc/pool/jmx/ConnectionPool.java?rev=765051&r1=765050&r2=765051&view=diff
==============================================================================
--- tomcat/trunk/modules/jdbc-pool/java/org/apache/tomcat/jdbc/pool/jmx/ConnectionPool.java (original)
+++ tomcat/trunk/modules/jdbc-pool/java/org/apache/tomcat/jdbc/pool/jmx/ConnectionPool.java Wed Apr 15 04:58:06 2009
@@ -17,12 +17,15 @@
/**
* @author Filip Hanik
*/
+import java.util.Iterator;
import java.util.Properties;
+import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.atomic.AtomicInteger;
import javax.management.MBeanNotificationInfo;
import javax.management.Notification;
import javax.management.NotificationBroadcasterSupport;
+import javax.management.NotificationListener;
import org.apache.juli.logging.Log;
import org.apache.juli.logging.LogFactory;
@@ -41,6 +44,11 @@
* sequence for JMX notifications
*/
protected AtomicInteger sequence = new AtomicInteger(0);
+
+ /**
+ * Listeners that are local and interested in our notifications, no need for JMX
+ */
+ protected ConcurrentLinkedQueue<NotificationListener> listeners = new ConcurrentLinkedQueue<NotificationListener>();
public ConnectionPool(org.apache.tomcat.jdbc.pool.ConnectionPool pool) {
super();
@@ -62,6 +70,8 @@
public static final String NOTIFY_INIT = "INIT FAILED";
public static final String NOTIFY_CONNECT = "CONNECTION FAILED";
public static final String NOTIFY_ABANDON = "CONNECTION ABANDONED";
+ public static final String SLOW_QUERY_NOTIFICATION = "SLOW QUERY";
+ public static final String FAILED_QUERY_NOTIFICATION = "FAILED QUERY";
@@ -76,7 +86,7 @@
}
public static MBeanNotificationInfo[] getDefaultNotificationInfo() {
- String[] types = new String[] {NOTIFY_INIT, NOTIFY_CONNECT, NOTIFY_ABANDON};
+ String[] types = new String[] {NOTIFY_INIT, NOTIFY_CONNECT, NOTIFY_ABANDON, SLOW_QUERY_NOTIFICATION, FAILED_QUERY_NOTIFICATION};
String name = Notification.class.getName();
String description = "A connection pool error condition was met.";
MBeanNotificationInfo info = new MBeanNotificationInfo(types, name, description);
@@ -96,8 +106,11 @@
this,
sequence.incrementAndGet(),
System.currentTimeMillis(),
- message!=null?message:"");
+ "["+type+"] "+message);
sendNotification(n);
+ for (NotificationListener listener : listeners) {
+ listener.handleNotification(n,this);
+ }
return true;
}catch (Exception x) {
if (log.isDebugEnabled()) {
@@ -108,6 +121,14 @@
}
+ public void addListener(NotificationListener list) {
+ listeners.add(list);
+ }
+
+ public boolean removeListener(NotificationListener list) {
+ return listeners.remove(list);
+ }
+
//=================================================================
// POOL STATS
//=================================================================
@@ -127,6 +148,14 @@
public boolean isPoolSweeperEnabled() {
return pool.getPoolProperties().isPoolSweeperEnabled();
}
+
+ public int getNumIdle() {
+ return getIdle();
+ }
+
+ public int getNumActive() {
+ return getNumActive();
+ }
//=================================================================
// POOL OPERATIONS
Modified: tomcat/trunk/modules/jdbc-pool/java/org/apache/tomcat/jdbc/pool/jmx/ConnectionPoolMBean.java
URL: http://svn.apache.org/viewvc/tomcat/trunk/modules/jdbc-pool/java/org/apache/tomcat/jdbc/pool/jmx/ConnectionPoolMBean.java?rev=765051&r1=765050&r2=765051&view=diff
==============================================================================
--- tomcat/trunk/modules/jdbc-pool/java/org/apache/tomcat/jdbc/pool/jmx/ConnectionPoolMBean.java (original)
+++ tomcat/trunk/modules/jdbc-pool/java/org/apache/tomcat/jdbc/pool/jmx/ConnectionPoolMBean.java Wed Apr 15 04:58:06 2009
@@ -30,7 +30,11 @@
public int getActive();
public boolean isPoolSweeperEnabled();
-
+
+ public int getNumIdle();
+
+ public int getNumActive();
+
//=================================================================
// POOL OPERATIONS
//=================================================================
Modified: tomcat/trunk/modules/jdbc-pool/java/org/apache/tomcat/jdbc/pool/mbeans-descriptors.xml
URL: http://svn.apache.org/viewvc/tomcat/trunk/modules/jdbc-pool/java/org/apache/tomcat/jdbc/pool/mbeans-descriptors.xml?rev=765051&r1=765050&r2=765051&view=diff
==============================================================================
--- tomcat/trunk/modules/jdbc-pool/java/org/apache/tomcat/jdbc/pool/mbeans-descriptors.xml (original)
+++ tomcat/trunk/modules/jdbc-pool/java/org/apache/tomcat/jdbc/pool/mbeans-descriptors.xml Wed Apr 15 04:58:06 2009
@@ -15,7 +15,7 @@
-->
<mbeans-descriptors>
- <mbean name="DiagnosticsPool"
+ <mbean name="TomcatJDBCPool"
description="Provides per diagnostic metrics and notifications for JDBC operations"
domain="tomcat"
group="jdbc"
@@ -36,11 +36,21 @@
type="java.lang.Integer"
writeable="false"/>
+ <attribute name="numIdle"
+ description="Same as the idle attribute"
+ type="java.lang.Integer"
+ writeable="false"/>
+
<attribute name="active"
description="The number of established connections in the pool that are in use"
type="java.lang.Integer"
writeable="false"/>
+ <attribute name="numActive"
+ description="Same as the active attribute"
+ type="java.lang.Integer"
+ writeable="false"/>
+
<attribute name="poolSweeperEnabled"
description="Returns true if the pool has a background thread running"
type="java.lang.Boolean"
@@ -216,15 +226,6 @@
description="forces a validation of abandoned connections"
impact="ACTION"
returnType="void" />
-
-
- <notification name="jdbc-diagnostic"
- description="Notification issued when the request diagnostic actions kick in" >
- <notification-type>INIT FAILED</notification-type>
- <notification-type>CONNECTION FAILED</notification-type>
- <notification-type>CONNECTION ABANDONED</notification-type>
- </notification>
-
</mbean>
</mbeans-descriptors>
---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@tomcat.apache.org
For additional commands, e-mail: dev-help@tomcat.apache.org