diff --git a/src/main/java/com/alibaba/druid/filter/FilterChainImpl.java b/src/main/java/com/alibaba/druid/filter/FilterChainImpl.java index f864aa1118..452bd0c2f8 100644 --- a/src/main/java/com/alibaba/druid/filter/FilterChainImpl.java +++ b/src/main/java/com/alibaba/druid/filter/FilterChainImpl.java @@ -969,7 +969,14 @@ public class FilterChainImpl implements FilterChain { if (this.pos < filterSize) { return nextFilter().resultSet_getObject(this, resultSet, columnIndex); } - return resultSet.getResultSetRaw().getObject(columnIndex); + + Object obj = resultSet.getResultSetRaw().getObject(columnIndex); + + if (obj instanceof Clob) { + return wrap(resultSet.getStatementProxy().getConnectionProxy(), (Clob) obj); + } + + return obj; } @Override @@ -977,7 +984,14 @@ public class FilterChainImpl implements FilterChain { if (this.pos < filterSize) { return nextFilter().resultSet_getObject(this, resultSet, columnLabel); } - return resultSet.getResultSetRaw().getObject(columnLabel); + + Object obj = resultSet.getResultSetRaw().getObject(columnLabel); + + if (obj instanceof Clob) { + return wrap(resultSet.getStatementProxy().getConnectionProxy(), (Clob) obj); + } + + return obj; } @Override @@ -1623,7 +1637,14 @@ public class FilterChainImpl implements FilterChain { if (this.pos < filterSize) { return nextFilter().resultSet_getObject(this, resultSet, columnIndex, map); } - return resultSet.getResultSetRaw().getObject(columnIndex, map); + + Object obj = resultSet.getResultSetRaw().getObject(columnIndex, map); + + if (obj instanceof Clob) { + return wrap(resultSet.getStatementProxy().getConnectionProxy(), (Clob) obj); + } + + return obj; } @Override @@ -1670,7 +1691,14 @@ public class FilterChainImpl implements FilterChain { if (this.pos < filterSize) { return nextFilter().resultSet_getObject(this, resultSet, columnLabel, map); } - return resultSet.getResultSetRaw().getObject(columnLabel, map); + + Object obj = resultSet.getResultSetRaw().getObject(columnLabel, map); + + if (obj instanceof Clob) { + return wrap(resultSet.getStatementProxy().getConnectionProxy(), (Clob) obj); + } + + return obj; } @Override @@ -3349,6 +3377,10 @@ public class FilterChainImpl implements FilterChain { return wrap(statement, (ResultSet) obj); } + if (obj instanceof Clob) { + return wrap(statement.getConnectionProxy(), (Clob) obj); + } + return obj; } @@ -3365,6 +3397,10 @@ public class FilterChainImpl implements FilterChain { return wrap(statement, (ResultSet) obj); } + if (obj instanceof Clob) { + return wrap(statement.getConnectionProxy(), (Clob) obj); + } + return obj; } @@ -3380,6 +3416,10 @@ public class FilterChainImpl implements FilterChain { if (obj instanceof ResultSet) { return wrap(statement, (ResultSet) obj); } + + if (obj instanceof Clob) { + return wrap(statement.getConnectionProxy(), (Clob) obj); + } return obj; } @@ -3396,6 +3436,10 @@ public class FilterChainImpl implements FilterChain { if (obj instanceof ResultSet) { return wrap(statement, (ResultSet) obj); } + + if (obj instanceof Clob) { + return wrap(statement.getConnectionProxy(), (Clob) obj); + } return obj; } diff --git a/src/main/java/com/alibaba/druid/filter/stat/StatFilter.java b/src/main/java/com/alibaba/druid/filter/stat/StatFilter.java index 47c8524b38..c86e200069 100644 --- a/src/main/java/com/alibaba/druid/filter/stat/StatFilter.java +++ b/src/main/java/com/alibaba/druid/filter/stat/StatFilter.java @@ -31,6 +31,7 @@ import com.alibaba.druid.filter.FilterEventAdapter; import com.alibaba.druid.pool.DruidDataSource; import com.alibaba.druid.pool.DruidPooledConnection; import com.alibaba.druid.proxy.jdbc.CallableStatementProxy; +import com.alibaba.druid.proxy.jdbc.ClobProxy; import com.alibaba.druid.proxy.jdbc.ConnectionProxy; import com.alibaba.druid.proxy.jdbc.DataSourceProxy; import com.alibaba.druid.proxy.jdbc.JdbcParameter; @@ -563,7 +564,7 @@ public class StatFilter extends FilterEventAdapter implements StatFilterMBean { dataSourceStat.getResultSetStat().beforeOpen(); resultSet.setConstructNano(); - + StatFilterContext.getInstance().resultSet_open(); } @@ -592,7 +593,7 @@ public class StatFilter extends FilterEventAdapter implements StatFilterMBean { } chain.resultSet_close(resultSet); - + StatFilterContext.getInstance().resultSet_close(nanos); } @@ -650,29 +651,185 @@ public class StatFilter extends FilterEventAdapter implements StatFilterMBean { return null; } + @Override public void dataSource_releaseConnection(FilterChain chain, DruidPooledConnection conn) throws SQLException { chain.dataSource_recycle(conn); long nanos = System.nanoTime() - conn.getConnectedTimeNano(); long millis = nanos / (1000L * 1000L); + JdbcDataSourceStat dataSourceStat = chain.getDataSource().getDataSourceStat(); dataSourceStat.getConnectionHoldHistogram().record(millis); StatFilterContext.getInstance().pool_connection_close(nanos); } + @Override public DruidPooledConnection dataSource_getConnection(FilterChain chain, DruidDataSource dataSource, long maxWaitMillis) throws SQLException { DruidPooledConnection conn = chain.dataSource_connect(dataSource, maxWaitMillis); if (conn != null) { conn.setConnectedTimeNano(System.nanoTime()); - + StatFilterContext.getInstance().pool_connection_open(); } return conn; } + @Override + public Clob resultSet_getClob(FilterChain chain, ResultSetProxy resultSet, int columnIndex) throws SQLException { + Clob clob = chain.resultSet_getClob(resultSet, columnIndex); + + if (clob != null) { + clobOpenAfter(chain.getDataSource().getDataSourceStat()); + } + + return clob; + } + + @Override + public Clob resultSet_getClob(FilterChain chain, ResultSetProxy resultSet, String columnLabel) throws SQLException { + Clob clob = chain.resultSet_getClob(resultSet, columnLabel); + + if (clob != null) { + clobOpenAfter(chain.getDataSource().getDataSourceStat()); + } + + return clob; + } + + @Override + public Clob callableStatement_getClob(FilterChain chain, CallableStatementProxy statement, int parameterIndex) + throws SQLException { + Clob clob = chain.callableStatement_getClob(statement, parameterIndex); + + if (clob != null) { + clobOpenAfter(chain.getDataSource().getDataSourceStat()); + } + + return clob; + } + + @Override + public Clob callableStatement_getClob(FilterChain chain, CallableStatementProxy statement, String parameterName) + throws SQLException { + Clob clob = chain.callableStatement_getClob(statement, parameterName); + + if (clob != null) { + clobOpenAfter(chain.getDataSource().getDataSourceStat()); + } + + return clob; + } + + @Override + public Object resultSet_getObject(FilterChain chain, ResultSetProxy result, int columnIndex) throws SQLException { + Object obj = chain.resultSet_getObject(result, columnIndex); + + if (obj instanceof Clob) { + clobOpenAfter(chain.getDataSource().getDataSourceStat()); + } + + return obj; + } + + @Override + public Object resultSet_getObject(FilterChain chain, ResultSetProxy result, int columnIndex, + java.util.Map> map) throws SQLException { + Object obj = chain.resultSet_getObject(result, columnIndex, map); + + if (obj instanceof Clob) { + clobOpenAfter(chain.getDataSource().getDataSourceStat()); + } + + return obj; + } + + @Override + public Object resultSet_getObject(FilterChain chain, ResultSetProxy result, String columnLabel) throws SQLException { + Object obj = chain.resultSet_getObject(result, columnLabel); + + if (obj instanceof Clob) { + clobOpenAfter(chain.getDataSource().getDataSourceStat()); + } + + return obj; + } + + @Override + public Object resultSet_getObject(FilterChain chain, ResultSetProxy result, String columnLabel, + java.util.Map> map) throws SQLException { + Object obj = chain.resultSet_getObject(result, columnLabel, map); + + if (obj instanceof Clob) { + clobOpenAfter(chain.getDataSource().getDataSourceStat()); + } + + return obj; + } + + @Override + public Object callableStatement_getObject(FilterChain chain, CallableStatementProxy statement, int parameterIndex) + throws SQLException { + Object obj = chain.callableStatement_getObject(statement, parameterIndex); + + if (obj instanceof Clob) { + clobOpenAfter(chain.getDataSource().getDataSourceStat()); + } + + return obj; + } + + @Override + public Object callableStatement_getObject(FilterChain chain, CallableStatementProxy statement, int parameterIndex, + java.util.Map> map) throws SQLException { + Object obj = chain.callableStatement_getObject(statement, parameterIndex, map); + + if (obj instanceof Clob) { + clobOpenAfter(chain.getDataSource().getDataSourceStat()); + } + + return obj; + } + + @Override + public Object callableStatement_getObject(FilterChain chain, CallableStatementProxy statement, String parameterName) + throws SQLException { + Object obj = chain.callableStatement_getObject(statement, parameterName); + + if (obj instanceof Clob) { + clobOpenAfter(chain.getDataSource().getDataSourceStat()); + } + + return obj; + } + + @Override + public Object callableStatement_getObject(FilterChain chain, CallableStatementProxy statement, + String parameterName, java.util.Map> map) + throws SQLException { + Object obj = chain.callableStatement_getObject(statement, parameterName, map); + + if (obj instanceof Clob) { + clobOpenAfter(chain.getDataSource().getDataSourceStat()); + } + + return obj; + } + + private void clobOpenAfter(JdbcDataSourceStat dataSourceStat) { + dataSourceStat.incrementClobOpenCount(); + } + + @Override + public void clob_free(FilterChain chain, ClobProxy wrapper) throws SQLException { + chain.clob_free(wrapper); + + JdbcDataSourceStat dataSourceStat = chain.getDataSource().getDataSourceStat(); + dataSourceStat.incrementClobFreeCount(); + } + } diff --git a/src/main/java/com/alibaba/druid/stat/JdbcDataSourceStat.java b/src/main/java/com/alibaba/druid/stat/JdbcDataSourceStat.java index 9c1c04d2c5..8f5d92674b 100644 --- a/src/main/java/com/alibaba/druid/stat/JdbcDataSourceStat.java +++ b/src/main/java/com/alibaba/druid/stat/JdbcDataSourceStat.java @@ -22,6 +22,7 @@ import java.util.Map; import java.util.Properties; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentMap; +import java.util.concurrent.atomic.AtomicLong; import java.util.concurrent.locks.ReentrantReadWriteLock; import javax.management.JMException; @@ -65,6 +66,9 @@ public class JdbcDataSourceStat implements JdbcDataSourceStatMBean { private final ConcurrentMap connections = new ConcurrentHashMap(); + private final AtomicLong clobOpenCount = new AtomicLong(); + private final AtomicLong clobFreeCount = new AtomicLong(); + public JdbcDataSourceStat(String name, String url){ this(name, url, null); } @@ -98,6 +102,9 @@ public class JdbcDataSourceStat implements JdbcDataSourceStatMBean { } public void reset() { + clobOpenCount.set(0); + clobFreeCount.set(0); + connectionStat.reset(); statementStat.reset(); resultSetStat.reset(); @@ -171,7 +178,7 @@ public class JdbcDataSourceStat implements JdbcDataSourceStatMBean { return null; } - + public JdbcSqlStat getSqlStat(int id) { return getSqlStat((long) id); } @@ -305,4 +312,20 @@ public class JdbcDataSourceStat implements JdbcDataSourceStatMBean { return connectionStat.getHistorgramValues(); } + public long getClobOpenCount() { + return clobOpenCount.get(); + } + + public void incrementClobOpenCount() { + clobOpenCount.incrementAndGet(); + } + + public long getClobFreeCount() { + return clobFreeCount.get(); + } + + public void incrementClobFreeCount() { + clobFreeCount.incrementAndGet(); + } + } diff --git a/src/main/java/com/alibaba/druid/support/http/WebStatFilter.java b/src/main/java/com/alibaba/druid/support/http/WebStatFilter.java index 74b8ea44ee..3a35a38ce5 100644 --- a/src/main/java/com/alibaba/druid/support/http/WebStatFilter.java +++ b/src/main/java/com/alibaba/druid/support/http/WebStatFilter.java @@ -96,6 +96,7 @@ public class WebStatFilter implements Filter { int index = requestURI.indexOf(";jsessionid="); if (index != -1) { requestURI = requestURI.substring(0, index); + uriStat = webAppStat.getURIStat(requestURI, false); } }