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 d710759a2f..5d654c4edb 100644 --- a/src/main/java/com/alibaba/druid/filter/stat/StatFilter.java +++ b/src/main/java/com/alibaba/druid/filter/stat/StatFilter.java @@ -15,9 +15,15 @@ */ package com.alibaba.druid.filter.stat; +import java.io.InputStream; +import java.sql.Blob; +import java.sql.Clob; +import java.sql.NClob; import java.sql.SQLException; import java.sql.Savepoint; +import java.util.ArrayList; import java.util.Date; +import java.util.List; import java.util.Properties; import java.util.concurrent.ConcurrentMap; import java.util.concurrent.atomic.AtomicLong; @@ -50,27 +56,30 @@ import com.alibaba.druid.stat.JdbcStatementStat; */ public class StatFilter extends FilterEventAdapter implements StatFilterMBean { - private final static Log LOG = LogFactory.getLog(StatFilter.class); + private final static Log LOG = LogFactory.getLog(StatFilter.class); - public final static String ATTR_SQL = "stat.sql"; - public final static String ATTR_UPDATE_COUNT = "stat.updteCount"; - public final static String ATTR_TRANSACTION = "stat.tx"; + public final static String ATTR_SQL = "stat.sql"; + public final static String ATTR_UPDATE_COUNT = "stat.updteCount"; + public final static String ATTR_TRANSACTION = "stat.tx"; + + protected JdbcDataSourceStat dataSourceStat; - protected JdbcDataSourceStat dataSourceStat; - @Deprecated - protected final JdbcStatementStat statementStat = JdbcStatManager.getInstance().getStatementStat(); - + protected final JdbcStatementStat statementStat = JdbcStatManager.getInstance().getStatementStat(); + @Deprecated - protected final JdbcResultSetStat resultSetStat = JdbcStatManager.getInstance().getResultSetStat(); + protected final JdbcResultSetStat resultSetStat = JdbcStatManager.getInstance().getResultSetStat(); - private boolean connectionStackTraceEnable = false; + private boolean connectionStackTraceEnable = false; - protected DataSourceProxy dataSource; + protected DataSourceProxy dataSource; - protected final AtomicLong resetCount = new AtomicLong(); + protected final AtomicLong resetCount = new AtomicLong(); - protected int maxSqlStatCount = 1000 * 100; + protected int maxSqlStatCount = 1000 * 10; + + // 3 seconds is slow sql + protected long slowSqlMillis = 3 * 1000; public StatFilter(){ String property = System.getProperty("druid.stat.maxSqlStatCount"); @@ -78,7 +87,7 @@ public class StatFilter extends FilterEventAdapter implements StatFilterMBean { try { maxSqlStatCount = Integer.parseInt(property); } catch (Exception e) { - + LOG.error("get property error 'druid.stat.maxSqlStatCount' : " + property); } } } @@ -251,8 +260,6 @@ public class StatFilter extends FilterEventAdapter implements StatFilterMBean { @Override protected void statementExecuteUpdateAfter(StatementProxy statement, String sql, int updateCount) { internalAfterStatementExecute(statement, updateCount); - - // super.statementExecuteUpdateAfter(statement, sql, updateCount); } @Override @@ -396,6 +403,36 @@ public class StatFilter extends FilterEventAdapter implements StatFilterMBean { sqlStat.decrementExecutingCount(); sqlStat.addExecuteTime(nanoSpan); + + long millis = nanoSpan / (1000 * 1000); + if (millis >= slowSqlMillis) { + List lastSlowParameters = new ArrayList(); + for (Object value : statement.getParameters().values()) { + if (value == null) { + lastSlowParameters.add("null"); + } else if (value instanceof String) { + lastSlowParameters.add("'" + value.toString() + "'"); + } else if (value instanceof Number) { + lastSlowParameters.add(value.toString()); + } else if (value instanceof java.util.Date) { + java.util.Date date = (java.util.Date) value; + lastSlowParameters.add(date.getClass().getSimpleName() + "(" + date.getTime() + ")"); + } else if (value instanceof Boolean) { + lastSlowParameters.add(value.toString()); + } else if (value instanceof InputStream) { + lastSlowParameters.add(""); + } else if (value instanceof Clob) { + lastSlowParameters.add(""); + } else if (value instanceof NClob) { + lastSlowParameters.add(""); + } else if (value instanceof Blob) { + lastSlowParameters.add(""); + } else { + lastSlowParameters.add("<" + value.getClass() + ">"); + } + } + sqlStat.setLastSlowParameters(lastSlowParameters); + } } if (updateCountArray.length == 1) { 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 a8d17c432f..324a1516fc 100644 --- a/src/main/java/com/alibaba/druid/proxy/jdbc/StatementProxy.java +++ b/src/main/java/com/alibaba/druid/proxy/jdbc/StatementProxy.java @@ -17,6 +17,7 @@ package com.alibaba.druid.proxy.jdbc; import java.sql.Statement; import java.util.List; +import java.util.Map; /** * @author wenshao @@ -32,4 +33,6 @@ public interface StatementProxy extends Statement, WrapperProxy { String getBatchSql(); String getLastExecuteSql(); + + Map getParameters(); } 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 25d59b434c..14e7d594c4 100644 --- a/src/main/java/com/alibaba/druid/proxy/jdbc/StatementProxyImpl.java +++ b/src/main/java/com/alibaba/druid/proxy/jdbc/StatementProxyImpl.java @@ -22,7 +22,9 @@ import java.sql.SQLFeatureNotSupportedException; import java.sql.SQLWarning; import java.sql.Statement; import java.util.ArrayList; +import java.util.Collections; import java.util.List; +import java.util.Map; import com.alibaba.druid.filter.FilterChain; import com.alibaba.druid.filter.FilterChainImpl; @@ -323,4 +325,9 @@ public class StatementProxyImpl extends WrapperProxyImpl implements StatementPro return super.unwrap(iface); } + + @Override + public Map getParameters() { + return Collections.emptyMap(); + } } diff --git a/src/main/java/com/alibaba/druid/stat/JdbcResultSetStat.java b/src/main/java/com/alibaba/druid/stat/JdbcResultSetStat.java index f893c418f3..da8ab5c5d1 100644 --- a/src/main/java/com/alibaba/druid/stat/JdbcResultSetStat.java +++ b/src/main/java/com/alibaba/druid/stat/JdbcResultSetStat.java @@ -164,7 +164,7 @@ public class JdbcResultSetStat implements JdbcResultSetStatMBean { @Override public long getHoldMillisTotal() { - return JdbcStatManager.getInstance().getResultSetStat().getAliveNanoTotal() / (1000 * 1000); + return getAliveNanoTotal() / (1000 * 1000); } @Override diff --git a/src/main/java/com/alibaba/druid/stat/JdbcSqlStat.java b/src/main/java/com/alibaba/druid/stat/JdbcSqlStat.java index 9583109dfa..a607527784 100644 --- a/src/main/java/com/alibaba/druid/stat/JdbcSqlStat.java +++ b/src/main/java/com/alibaba/druid/stat/JdbcSqlStat.java @@ -17,6 +17,7 @@ package com.alibaba.druid.stat; import java.util.Date; import java.util.HashMap; +import java.util.List; import java.util.Map; import java.util.concurrent.atomic.AtomicLong; @@ -64,6 +65,8 @@ public final class JdbcSqlStat implements JdbcSqlStatMBean { private final AtomicLong inTransactionCount = new AtomicLong(); + private List lastSlowParameters; + private final Histogram histogram = new Histogram(new long[] { // // 1, 10, 100, 1000, 10 * 1000, // @@ -75,6 +78,14 @@ public final class JdbcSqlStat implements JdbcSqlStatMBean { this.sql = sql; } + public List getLastSlowParameters() { + return lastSlowParameters; + } + + public void setLastSlowParameters(List lastSlowParameters) { + this.lastSlowParameters = lastSlowParameters; + } + public String getDbType() { return dbType; }