From 449eff3f6e09db4c33e89fe017629fffca27d239 Mon Sep 17 00:00:00 2001 From: axmanwang Date: Mon, 16 Apr 2012 10:31:17 +0800 Subject: [PATCH] add stat attribute --- .../alibaba/druid/filter/stat/StatFilter.java | 49 +++++------ .../ha/MultiDataSourcePreparedStatement.java | 3 +- .../jdbc/PreparedStatementProxyImpl.java | 6 +- .../druid/proxy/jdbc/StatementProxy.java | 4 + .../druid/proxy/jdbc/StatementProxyImpl.java | 36 ++++++++- .../com/alibaba/druid/stat/JdbcSqlStat.java | 81 +++++++++++++++++-- .../alibaba/druid/stat/JdbcStatContext.java | 10 +++ 7 files changed, 149 insertions(+), 40 deletions(-) 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 a11db0575b..0b6461eda7 100644 --- a/src/main/java/com/alibaba/druid/filter/stat/StatFilter.java +++ b/src/main/java/com/alibaba/druid/filter/stat/StatFilter.java @@ -41,6 +41,7 @@ import com.alibaba.druid.proxy.jdbc.DataSourceProxy; import com.alibaba.druid.proxy.jdbc.JdbcParameter; import com.alibaba.druid.proxy.jdbc.PreparedStatementProxy; import com.alibaba.druid.proxy.jdbc.ResultSetProxy; +import com.alibaba.druid.proxy.jdbc.StatementExecuteType; import com.alibaba.druid.proxy.jdbc.StatementProxy; import com.alibaba.druid.sql.visitor.ParameterizedOutputVisitorUtils; import com.alibaba.druid.stat.JdbcConnectionStat; @@ -293,6 +294,9 @@ public class StatFilter extends FilterEventAdapter implements StatFilterMBean { chain.statement_close(statement); dataSourceStat.getStatementStat().incrementStatementCloseCounter(); + JdbcStatManager.getInstance().getStatContext().setName(null); + JdbcStatManager.getInstance().getStatContext().setFile(null); + JdbcStatManager.getInstance().getStatContext().setSql(null); } @Override @@ -394,25 +398,6 @@ public class StatFilter extends FilterEventAdapter implements StatFilterMBean { LOG.error("getAutoCommit error", e); } } - - statement.getAttributes().put(ATTR_UPDATE_COUNT, 0); - } - - @Override - public int statement_getUpdateCount(FilterChain chain, StatementProxy statement) throws SQLException { - int updateCount = chain.statement_getUpdateCount(statement); - - Integer attr = (Integer) statement.getAttributes().get(ATTR_UPDATE_COUNT); - if (attr == null) { - statement.getAttributes().put(ATTR_UPDATE_COUNT, updateCount); - - final JdbcSqlStat sqlStat = statement.getSqlStat(); - if (sqlStat != null) { - sqlStat.addUpdateCount(updateCount); - } - } - - return updateCount; } private final void internalAfterStatementExecute(StatementProxy statement, int... updateCountArray) { @@ -435,8 +420,16 @@ public class StatFilter extends FilterEventAdapter implements StatFilterMBean { } sqlStat.decrementRunningCount(); - sqlStat.addExecuteTime(nanoSpan); + sqlStat.addExecuteTime(statement.getLastExecuteType(), nanoSpan); statement.setLastExecuteTimeNano(nanoSpan); + if ((!statement.isFirstResultSet()) && statement.getLastExecuteType() == StatementExecuteType.Execute) { + try { + int updateCount = statement.getUpdateCount(); + sqlStat.addUpdateCount(updateCount); + } catch (SQLException e) { + LOG.error("getUpdateCount error", e); + } + } long millis = nanoSpan / (1000 * 1000); if (millis >= slowSqlMillis) { @@ -505,10 +498,6 @@ public class StatFilter extends FilterEventAdapter implements StatFilterMBean { sqlStat.setLastSlowParameters(buf.toString()); } } - - if (updateCountArray.length == 1) { - statement.getAttributes().put(ATTR_UPDATE_COUNT, updateCountArray[0]); - } } @Override @@ -530,7 +519,7 @@ public class StatFilter extends FilterEventAdapter implements StatFilterMBean { if (sqlStat != null) { sqlStat.error(error); - sqlStat.addExecuteTime(nanoSpan); + sqlStat.addExecuteTime(statement.getLastExecuteType(), nanoSpan); statement.setLastExecuteTimeNano(nanoSpan); } @@ -717,9 +706,13 @@ public class StatFilter extends FilterEventAdapter implements StatFilterMBean { } public JdbcSqlStat createSqlStat(StatementProxy statement, String sql) { - - sql = mergeSql(sql); - return dataSourceStat.createSqlStat(sql); + String contextSql = JdbcStatManager.getInstance().getStatContext().getSql(); + if (contextSql != null && contextSql.length() > 0) { + return dataSourceStat.createSqlStat(contextSql); + } else { + sql = mergeSql(sql); + return dataSourceStat.createSqlStat(sql); + } } public JdbcSqlStat getSqlCounter(String sql) { diff --git a/src/main/java/com/alibaba/druid/pool/ha/MultiDataSourcePreparedStatement.java b/src/main/java/com/alibaba/druid/pool/ha/MultiDataSourcePreparedStatement.java index 7379b508e3..89c5e3a7bd 100644 --- a/src/main/java/com/alibaba/druid/pool/ha/MultiDataSourcePreparedStatement.java +++ b/src/main/java/com/alibaba/druid/pool/ha/MultiDataSourcePreparedStatement.java @@ -29,7 +29,8 @@ public class MultiDataSourcePreparedStatement extends PreparedStatementProxyImpl return this.statement.execute(); } - return chain.preparedStatement_execute(this); + firstResultSet = chain.preparedStatement_execute(this); + return firstResultSet; } @Override diff --git a/src/main/java/com/alibaba/druid/proxy/jdbc/PreparedStatementProxyImpl.java b/src/main/java/com/alibaba/druid/proxy/jdbc/PreparedStatementProxyImpl.java index e5a3f48759..fd45020c2f 100644 --- a/src/main/java/com/alibaba/druid/proxy/jdbc/PreparedStatementProxyImpl.java +++ b/src/main/java/com/alibaba/druid/proxy/jdbc/PreparedStatementProxyImpl.java @@ -85,16 +85,20 @@ public class PreparedStatementProxyImpl extends StatementProxyImpl implements Pr @Override public boolean execute() throws SQLException { - return createChain().preparedStatement_execute(this); + lastExecuteType = StatementExecuteType.Execute; + firstResultSet = createChain().preparedStatement_execute(this); + return firstResultSet; } @Override public ResultSet executeQuery() throws SQLException { + lastExecuteType = StatementExecuteType.ExecuteUpdate; return createChain().preparedStatement_executeQuery(this); } @Override public int executeUpdate() throws SQLException { + lastExecuteType = StatementExecuteType.ExecuteUpdate; return createChain().preparedStatement_executeUpdate(this); } diff --git a/src/main/java/com/alibaba/druid/proxy/jdbc/StatementProxy.java b/src/main/java/com/alibaba/druid/proxy/jdbc/StatementProxy.java index 3e8e517707..9a11baddf6 100644 --- a/src/main/java/com/alibaba/druid/proxy/jdbc/StatementProxy.java +++ b/src/main/java/com/alibaba/druid/proxy/jdbc/StatementProxy.java @@ -36,6 +36,8 @@ public interface StatementProxy extends Statement, WrapperProxy { JdbcSqlStat getSqlStat(); + StatementExecuteType getLastExecuteType(); + void setSqlStat(JdbcSqlStat sqlStat); String getLastExecuteSql(); @@ -44,4 +46,6 @@ public interface StatementProxy extends Statement, WrapperProxy { void setLastExecuteTimeNano(long nano); Map getParameters(); + + boolean isFirstResultSet(); } diff --git a/src/main/java/com/alibaba/druid/proxy/jdbc/StatementProxyImpl.java b/src/main/java/com/alibaba/druid/proxy/jdbc/StatementProxyImpl.java index afb6625933..57754885c2 100644 --- a/src/main/java/com/alibaba/druid/proxy/jdbc/StatementProxyImpl.java +++ b/src/main/java/com/alibaba/druid/proxy/jdbc/StatementProxyImpl.java @@ -29,6 +29,8 @@ import java.util.Map; import com.alibaba.druid.filter.FilterChain; import com.alibaba.druid.filter.FilterChainImpl; import com.alibaba.druid.stat.JdbcSqlStat; +import com.alibaba.druid.stat.JdbcStatContext; +import com.alibaba.druid.stat.JdbcStatManager; /** * @author wenshao @@ -41,8 +43,11 @@ public class StatementProxyImpl extends WrapperProxyImpl implements StatementPro protected String lastExecuteSql; private long lastExecuteTimeNano; protected JdbcSqlStat sqlStat; + protected boolean firstResultSet; protected ArrayList batchSqlList; + + protected StatementExecuteType lastExecuteType; public StatementProxyImpl(ConnectionProxy connection, Statement statement, long id){ super(statement, id); @@ -100,59 +105,74 @@ public class StatementProxyImpl extends WrapperProxyImpl implements StatementPro @Override public boolean execute(String sql) throws SQLException { lastExecuteSql = sql; - return createChain().statement_execute(this, sql); + lastExecuteType = StatementExecuteType.Execute; + + firstResultSet = createChain().statement_execute(this, sql); + return firstResultSet; } @Override public boolean execute(String sql, int autoGeneratedKeys) throws SQLException { lastExecuteSql = sql; - return createChain().statement_execute(this, sql, autoGeneratedKeys); + lastExecuteType = StatementExecuteType.Execute; + firstResultSet = createChain().statement_execute(this, sql, autoGeneratedKeys); + return firstResultSet; } @Override public boolean execute(String sql, int[] columnIndexes) throws SQLException { lastExecuteSql = sql; - return createChain().statement_execute(this, sql, columnIndexes); + lastExecuteType = StatementExecuteType.Execute; + firstResultSet = createChain().statement_execute(this, sql, columnIndexes); + return firstResultSet; } @Override public boolean execute(String sql, String[] columnNames) throws SQLException { lastExecuteSql = sql; - return createChain().statement_execute(this, sql, columnNames); + lastExecuteType = StatementExecuteType.Execute; + firstResultSet = createChain().statement_execute(this, sql, columnNames); + return firstResultSet; } @Override public int[] executeBatch() throws SQLException { + lastExecuteType = StatementExecuteType.ExecuteBatch; return createChain().statement_executeBatch(this); } @Override public ResultSet executeQuery(String sql) throws SQLException { lastExecuteSql = sql; + lastExecuteType = StatementExecuteType.ExecuteQuery; return createChain().statement_executeQuery(this, sql); } @Override public int executeUpdate(String sql) throws SQLException { lastExecuteSql = sql; + lastExecuteType = StatementExecuteType.ExecuteUpdate; return createChain().statement_executeUpdate(this, sql); } @Override public int executeUpdate(String sql, int autoGeneratedKeys) throws SQLException { lastExecuteSql = sql; + lastExecuteType = StatementExecuteType.ExecuteUpdate; return createChain().statement_executeUpdate(this, sql, autoGeneratedKeys); } @Override public int executeUpdate(String sql, int[] columnIndexes) throws SQLException { lastExecuteSql = sql; + lastExecuteType = StatementExecuteType.ExecuteUpdate; return createChain().statement_executeUpdate(this, sql, columnIndexes); } @Override public int executeUpdate(String sql, String[] columnNames) throws SQLException { lastExecuteSql = sql; + lastExecuteType = StatementExecuteType.ExecuteUpdate; return createChain().statement_executeUpdate(this, sql, columnNames); } @@ -344,4 +364,12 @@ public class StatementProxyImpl extends WrapperProxyImpl implements StatementPro public void setLastExecuteTimeNano(long lastExecuteTimeNano) { this.lastExecuteTimeNano = lastExecuteTimeNano; } + + public StatementExecuteType getLastExecuteType() { + return lastExecuteType; + } + + public boolean isFirstResultSet() { + return firstResultSet; + } } diff --git a/src/main/java/com/alibaba/druid/stat/JdbcSqlStat.java b/src/main/java/com/alibaba/druid/stat/JdbcSqlStat.java index 63ec6bbe58..62c5e481b6 100644 --- a/src/main/java/com/alibaba/druid/stat/JdbcSqlStat.java +++ b/src/main/java/com/alibaba/druid/stat/JdbcSqlStat.java @@ -27,6 +27,7 @@ import javax.management.openmbean.CompositeType; import javax.management.openmbean.OpenType; import javax.management.openmbean.SimpleType; +import com.alibaba.druid.proxy.jdbc.StatementExecuteType; import com.alibaba.druid.util.Histogram; import com.alibaba.druid.util.IOUtils; import com.alibaba.druid.util.JMXUtils; @@ -76,7 +77,26 @@ public final class JdbcSqlStat implements JdbcSqlStatMBean { 100 * 1000, 1000 * 1000 // }); + + private final Histogram executeAndResultHoldTimeHistogram = new Histogram(new long[] { // + // + 1, 10, 100, 1000, 10 * 1000, // + 100 * 1000, 1000 * 1000 +// + }); + + private final Histogram fetchRowCountHistogram = new Histogram(new long[] { // + 10, 100, 1000, 10 * 1000 + }); + + + private final Histogram updateCountHistogram = new Histogram(new long[] { // + 10, 100, 1000, 10 * 1000 + }); + + + public JdbcSqlStat(String sql){ this.sql = sql; } @@ -186,6 +206,9 @@ public final class JdbcSqlStat implements JdbcSqlStatMBean { inTransactionCount.set(0); resultSetHoldTimeNano.set(0); executeAndResultSetHoldTime.set(0); + fetchRowCountHistogram.reset(); + updateCountHistogram.reset(); + executeAndResultHoldTimeHistogram.reset(); } public long getConcurrentMax() { @@ -198,6 +221,9 @@ public final class JdbcSqlStat implements JdbcSqlStatMBean { public void addUpdateCount(int delta) { this.updateCount.addAndGet(delta); + this.updateCountHistogram.recode(delta); + this.fetchRowCountHistogram.recode(0); + } public long getUpdateCount() { @@ -248,6 +274,8 @@ public final class JdbcSqlStat implements JdbcSqlStatMBean { public void addFetchRowCount(long delta) { this.fetchRowCount.addAndGet(delta); + this.fetchRowCountHistogram.recode(delta); + } public void addExecuteBatchCount(long batchSize) { @@ -304,6 +332,13 @@ public final class JdbcSqlStat implements JdbcSqlStatMBean { public long getExecuteSuccessCount() { return executeSuccessCount.get(); } + + public void addExecuteTime(StatementExecuteType executeType, long nanoSpan) { + if (StatementExecuteType.ExecuteQuery != executeType) { + executeAndResultHoldTimeHistogram.recode((nanoSpan)/1000/1000); + } + addExecuteTime(nanoSpan); + } public void addExecuteTime(long nanoSpan) { executeSpanNanoTotal.addAndGet(nanoSpan); @@ -400,11 +435,18 @@ public final class JdbcSqlStat implements JdbcSqlStatMBean { SimpleType.LONG, // SimpleType.STRING, // - // 25 - + // 25 - 29 new ArrayType(SimpleType.LONG, true), // SimpleType.STRING, // SimpleType.LONG, // - SimpleType.LONG // + SimpleType.LONG, // + new ArrayType(SimpleType.LONG, true), // + + // 30 - + + new ArrayType(SimpleType.LONG, true), // + new ArrayType(SimpleType.LONG, true), // + }; String[] indexNames = { @@ -443,11 +485,19 @@ public final class JdbcSqlStat implements JdbcSqlStatMBean { "InTransactionCount", // "URL", // - // 25 - + // 25 - 29 "Histogram", // "LastSlowParameters", "ResultSetHoldTime", - "executeAndResultSetHoldTime" + "ExecuteAndResultSetHoldTime", + "FetchRowCountHistogram", + + // 30 + "EffectedRowCountHistogram", + "ExecuteAndResultHoldTimeHistogram" + + + // }; String[] indexDescriptions = indexNames; @@ -509,9 +559,14 @@ public final class JdbcSqlStat implements JdbcSqlStatMBean { map.put("Histogram", this.histogram.toArray()); // 25 map.put("LastSlowParameters", lastSlowParameters); // 26 - map.put("ResultSetHoldTime", getResultSetHoldTimeMilis()); // 26 - map.put("executeAndResultSetHoldTime", this.getExecuteAndResultSetHoldTimeMilis()); // 27 + map.put("ResultSetHoldTime", getResultSetHoldTimeMilis()); // 27 + map.put("ExecuteAndResultSetHoldTime", this.getExecuteAndResultSetHoldTimeMilis()); // 28 + map.put("FetchRowCountHistogram", this.getFetchRowCountHistogram().toArray()); // 29 + + map.put("EffectedRowCountHistogram", this.getUpdateCountHistogram().toArray()); // 30 + map.put("ExecuteAndResultHoldTimeHistogram", this.getExecuteAndResultHoldTimeHistogram().toArray()); // 30 + return map; } @@ -540,6 +595,18 @@ public final class JdbcSqlStat implements JdbcSqlStatMBean { } + public Histogram getFetchRowCountHistogram() { + return this.fetchRowCountHistogram; + } + + public Histogram getUpdateCountHistogram() { + return this.updateCountHistogram; + } + + public Histogram getExecuteAndResultHoldTimeHistogram() { + return this.executeAndResultHoldTimeHistogram; + } + public long getResultSetHoldTimeNano() { return resultSetHoldTimeNano.get(); @@ -556,5 +623,7 @@ public final class JdbcSqlStat implements JdbcSqlStatMBean { public void addResultSetHoldTimeNano(long statementExecuteNano, long resultHoldTimeNano) { resultSetHoldTimeNano.addAndGet(resultHoldTimeNano); executeAndResultSetHoldTime.addAndGet(statementExecuteNano+resultHoldTimeNano); + executeAndResultHoldTimeHistogram.recode((statementExecuteNano+resultHoldTimeNano)/1000/1000); + updateCountHistogram.recode(0); } } diff --git a/src/main/java/com/alibaba/druid/stat/JdbcStatContext.java b/src/main/java/com/alibaba/druid/stat/JdbcStatContext.java index bf540cbef9..84442a1f1f 100644 --- a/src/main/java/com/alibaba/druid/stat/JdbcStatContext.java +++ b/src/main/java/com/alibaba/druid/stat/JdbcStatContext.java @@ -19,6 +19,7 @@ public class JdbcStatContext { private String name; private String file; + private String sql; private String requestId; private boolean traceEnable; @@ -59,4 +60,13 @@ public class JdbcStatContext { this.file = file; } + public String getSql() { + return sql; + } + + public void setSql(String sql) { + this.sql = sql; + } + + }