mirror of
https://github.com/alibaba/druid.git
synced 2023-03-04 19:17:16 +00:00
add stat attribute
This commit is contained in:
@@ -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) {
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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<Integer, JdbcParameter> getParameters();
|
||||
|
||||
boolean isFirstResultSet();
|
||||
}
|
||||
|
||||
@@ -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<szujobs@hotmail.com>
|
||||
@@ -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<String> 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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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<Long>(SimpleType.LONG, true), //
|
||||
SimpleType.STRING, //
|
||||
SimpleType.LONG, //
|
||||
SimpleType.LONG //
|
||||
SimpleType.LONG, //
|
||||
new ArrayType<Long>(SimpleType.LONG, true), //
|
||||
|
||||
// 30 -
|
||||
|
||||
new ArrayType<Long>(SimpleType.LONG, true), //
|
||||
new ArrayType<Long>(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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user