From 43d41022f8e5695547f81c35db444c6840de66d8 Mon Sep 17 00:00:00 2001 From: wenshao Date: Sun, 19 Aug 2012 09:55:00 +0800 Subject: [PATCH] improve stat --- .../alibaba/druid/filter/stat/StatFilter.java | 20 ++-- .../druid/filter/stat/StatFilterContext.java | 50 +++++++++- .../stat/StatFilterContextListener.java | 12 +++ .../StatFilterContextListenerAdapter.java | 31 ++++++ .../druid/support/http/WebStatFilter.java | 42 ++++++++ .../support/http/stat/WebRequestStat.java | 39 ++++++++ .../druid/support/http/stat/WebURIStat.java | 99 ++++++++++++++----- .../support/spring/stat/SpringMethodStat.java | 68 ++++++++++++- .../http/resources/js/weburi-detail.js | 4 + .../support/http/resources/weburi-detail.html | 16 +++ 10 files changed, 348 insertions(+), 33 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 17233e80ba..47c8524b38 100644 --- a/src/main/java/com/alibaba/druid/filter/stat/StatFilter.java +++ b/src/main/java/com/alibaba/druid/filter/stat/StatFilter.java @@ -116,7 +116,7 @@ public class StatFilter extends FilterEventAdapter implements StatFilterMBean { public void setMergeSql(boolean mergeSql) { this.mergeSql = mergeSql; } - + @Deprecated public String mergeSql(String sql) { return this.mergeSql(sql, dbType); @@ -563,17 +563,19 @@ public class StatFilter extends FilterEventAdapter implements StatFilterMBean { dataSourceStat.getResultSetStat().beforeOpen(); resultSet.setConstructNano(); + + StatFilterContext.getInstance().resultSet_open(); } @Override public void resultSet_close(FilterChain chain, ResultSetProxy resultSet) throws SQLException { - long nanoSpan = System.nanoTime() - resultSet.getConstructNano(); + long nanos = System.nanoTime() - resultSet.getConstructNano(); int fetchRowCount = resultSet.getFetchRowCount(); JdbcDataSourceStat dataSourceStat = chain.getDataSource().getDataSourceStat(); - dataSourceStat.getResultSetStat().afterClose(nanoSpan); + dataSourceStat.getResultSetStat().afterClose(nanos); dataSourceStat.getResultSetStat().addFetchRowCount(fetchRowCount); dataSourceStat.getResultSetStat().incrementCloseCounter(); @@ -585,11 +587,13 @@ public class StatFilter extends FilterEventAdapter implements StatFilterMBean { if (sqlStat != null && resultSet.getCloseCount() == 0) { sqlStat.addFetchRowCount(fetchRowCount); long stmtExecuteNano = resultSet.getStatementProxy().getLastExecuteTimeNano(); - sqlStat.addResultSetHoldTimeNano(stmtExecuteNano, nanoSpan); + sqlStat.addResultSetHoldTimeNano(stmtExecuteNano, nanos); } } chain.resultSet_close(resultSet); + + StatFilterContext.getInstance().resultSet_close(nanos); } public JdbcConnectionStat.Entry getConnectionInfo(ConnectionProxy connection) { @@ -626,11 +630,11 @@ public class StatFilter extends FilterEventAdapter implements StatFilterMBean { return dataSourceStat.createSqlStat(contextSql); } else { String dbType = this.dbType; - + if (dbType == null) { dbType = dataSource.getDbType(); } - + sql = mergeSql(sql, dbType); return dataSourceStat.createSqlStat(sql); } @@ -654,6 +658,8 @@ public class StatFilter extends FilterEventAdapter implements StatFilterMBean { long millis = nanos / (1000L * 1000L); JdbcDataSourceStat dataSourceStat = chain.getDataSource().getDataSourceStat(); dataSourceStat.getConnectionHoldHistogram().record(millis); + + StatFilterContext.getInstance().pool_connection_close(nanos); } public DruidPooledConnection dataSource_getConnection(FilterChain chain, DruidDataSource dataSource, @@ -662,6 +668,8 @@ public class StatFilter extends FilterEventAdapter implements StatFilterMBean { if (conn != null) { conn.setConnectedTimeNano(System.nanoTime()); + + StatFilterContext.getInstance().pool_connection_open(); } return conn; diff --git a/src/main/java/com/alibaba/druid/filter/stat/StatFilterContext.java b/src/main/java/com/alibaba/druid/filter/stat/StatFilterContext.java index 895141b2ce..559e12502a 100644 --- a/src/main/java/com/alibaba/druid/filter/stat/StatFilterContext.java +++ b/src/main/java/com/alibaba/druid/filter/stat/StatFilterContext.java @@ -54,10 +54,58 @@ public class StatFilterContext { } public void commit() { - + for (int i = 0; i < listeners.size(); ++i) { + StatFilterContextListener listener = listeners.get(i); + listener.commit(); + } } public void rollback() { + for (int i = 0; i < listeners.size(); ++i) { + StatFilterContextListener listener = listeners.get(i); + listener.rollback(); + } + } + public void pool_connection_open() { + for (int i = 0; i < listeners.size(); ++i) { + StatFilterContextListener listener = listeners.get(i); + listener.pool_connect(); + } + } + + public void pool_connection_close(long nanos) { + for (int i = 0; i < listeners.size(); ++i) { + StatFilterContextListener listener = listeners.get(i); + listener.pool_close(nanos); + } + } + + public void physical_connection_connect() { + for (int i = 0; i < listeners.size(); ++i) { + StatFilterContextListener listener = listeners.get(i); + listener.physical_connection_connect(); + } + } + + public void physical_connection_close(long nanos) { + for (int i = 0; i < listeners.size(); ++i) { + StatFilterContextListener listener = listeners.get(i); + listener.physical_connection_close(nanos); + } + } + + public void resultSet_open() { + for (int i = 0; i < listeners.size(); ++i) { + StatFilterContextListener listener = listeners.get(i); + listener.resultSet_open(); + } + } + + public void resultSet_close(long nanos) { + for (int i = 0; i < listeners.size(); ++i) { + StatFilterContextListener listener = listeners.get(i); + listener.resultSet_close(nanos); + } } } diff --git a/src/main/java/com/alibaba/druid/filter/stat/StatFilterContextListener.java b/src/main/java/com/alibaba/druid/filter/stat/StatFilterContextListener.java index 00370690d9..16d258c337 100644 --- a/src/main/java/com/alibaba/druid/filter/stat/StatFilterContextListener.java +++ b/src/main/java/com/alibaba/druid/filter/stat/StatFilterContextListener.java @@ -13,4 +13,16 @@ public interface StatFilterContextListener { void commit(); void rollback(); + + void pool_connect(); + + void pool_close(long nanos); + + void physical_connection_connect(); + + void physical_connection_close(long nanos); + + void resultSet_open(); + + void resultSet_close(long nanos); } diff --git a/src/main/java/com/alibaba/druid/filter/stat/StatFilterContextListenerAdapter.java b/src/main/java/com/alibaba/druid/filter/stat/StatFilterContextListenerAdapter.java index df60e2ee92..5ab917340b 100644 --- a/src/main/java/com/alibaba/druid/filter/stat/StatFilterContextListenerAdapter.java +++ b/src/main/java/com/alibaba/druid/filter/stat/StatFilterContextListenerAdapter.java @@ -32,4 +32,35 @@ public class StatFilterContextListenerAdapter implements StatFilterContextListen } + @Override + public void pool_connect() { + + } + + @Override + public void pool_close(long nanos) { + + } + + @Override + public void physical_connection_connect() { + + } + + @Override + public void physical_connection_close(long nanos) { + + } + + @Override + public void resultSet_open() { + + } + + @Override + public void resultSet_close(long nanos) { + + } + + } 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 12667b6f1b..eb5033ad3d 100644 --- a/src/main/java/com/alibaba/druid/support/http/WebStatFilter.java +++ b/src/main/java/com/alibaba/druid/support/http/WebStatFilter.java @@ -452,6 +452,48 @@ public class WebStatFilter implements Filter { springMethodStat.incrementJdbcRollbackCount(); } } + + @Override + public void pool_connect() { + WebRequestStat reqStat = WebRequestStat.current(); + if (reqStat != null) { + reqStat.incrementJdbcPoolConnectCount(); + } + + SpringMethodStat springMethodStat = SpringMethodStat.current(); + if (springMethodStat != null) { + springMethodStat.incrementJdbcPoolConnectionOpenCount(); + } + } + + @Override + public void pool_close(long nanos) { + WebRequestStat reqStat = WebRequestStat.current(); + if (reqStat != null) { + reqStat.incrementJdbcPoolCloseCount(); + } + + SpringMethodStat springMethodStat = SpringMethodStat.current(); + if (springMethodStat != null) { + springMethodStat.incrementJdbcPoolConnectionOpenCount(); + } + } + + @Override + public void resultSet_open() { + WebRequestStat reqStat = WebRequestStat.current(); + if (reqStat != null) { + reqStat.incrementJdbcResultSetOpenCount(); + } + } + + @Override + public void resultSet_close(long nanos) { + WebRequestStat reqStat = WebRequestStat.current(); + if (reqStat != null) { + reqStat.incrementJdbcResultSetCloseCount(); + } + } } public final static class StatHttpServletResponseWrapper extends HttpServletResponseWrapper implements HttpServletResponse { diff --git a/src/main/java/com/alibaba/druid/support/http/stat/WebRequestStat.java b/src/main/java/com/alibaba/druid/support/http/stat/WebRequestStat.java index 071ab42ed7..5a0d724a5a 100644 --- a/src/main/java/com/alibaba/druid/support/http/stat/WebRequestStat.java +++ b/src/main/java/com/alibaba/druid/support/http/stat/WebRequestStat.java @@ -13,6 +13,12 @@ public class WebRequestStat { private long jdbcExecuteNano; private long jdbcExecuteErrorCount; + private long jdbcPoolConnectCount; + private long jdbcPoolCloseCount; + + private long jdbcResultSetOpenCount; + private long jdbcResultSetCloseCount; + public WebRequestStat(){ } @@ -115,4 +121,37 @@ public class WebRequestStat { public void incrementJdbcExecuteErrorCount() { jdbcExecuteErrorCount++; } + + public long getJdbcPoolConnectionOpenCount() { + return jdbcPoolConnectCount; + } + + public void incrementJdbcPoolConnectCount() { + this.jdbcPoolConnectCount++; + } + + public long getJdbcPoolConnectionCloseCount() { + return jdbcPoolCloseCount; + } + + public void incrementJdbcPoolCloseCount() { + this.jdbcPoolCloseCount++; + } + + public long getJdbcResultSetOpenCount() { + return jdbcResultSetOpenCount; + } + + public void incrementJdbcResultSetOpenCount() { + this.jdbcResultSetOpenCount++; + } + + public long getJdbcResultSetCloseCount() { + return jdbcResultSetCloseCount; + } + + public void incrementJdbcResultSetCloseCount() { + this.jdbcResultSetCloseCount++; + } + } diff --git a/src/main/java/com/alibaba/druid/support/http/stat/WebURIStat.java b/src/main/java/com/alibaba/druid/support/http/stat/WebURIStat.java index 8e1b4f9adc..507e89f64e 100644 --- a/src/main/java/com/alibaba/druid/support/http/stat/WebURIStat.java +++ b/src/main/java/com/alibaba/druid/support/http/stat/WebURIStat.java @@ -10,30 +10,36 @@ public class WebURIStat { private final String uri; - private final AtomicInteger runningCount = new AtomicInteger(); - private final AtomicInteger concurrentMax = new AtomicInteger(); - private final AtomicLong requestCount = new AtomicLong(0); - private final AtomicLong requestTimeNano = new AtomicLong(); + private final AtomicInteger runningCount = new AtomicInteger(); + private final AtomicInteger concurrentMax = new AtomicInteger(); + private final AtomicLong requestCount = new AtomicLong(0); + private final AtomicLong requestTimeNano = new AtomicLong(); - private final AtomicLong jdbcFetchRowCount = new AtomicLong(); - private final AtomicLong jdbcFetchRowPeak = new AtomicLong(); // 单次请求读取行数的峰值 + private final AtomicLong jdbcFetchRowCount = new AtomicLong(); + private final AtomicLong jdbcFetchRowPeak = new AtomicLong(); // 单次请求读取行数的峰值 - private final AtomicLong jdbcUpdateCount = new AtomicLong(); - private final AtomicLong jdbcUpdatePeak = new AtomicLong(); // 单次请求更新行数的峰值 + private final AtomicLong jdbcUpdateCount = new AtomicLong(); + private final AtomicLong jdbcUpdatePeak = new AtomicLong(); // 单次请求更新行数的峰值 - private final AtomicLong jdbcExecuteCount = new AtomicLong(); - private final AtomicLong jdbcExecuteErrorCount = new AtomicLong(); - private final AtomicLong jdbcExecutePeak = new AtomicLong(); // 单次请求执行SQL次数的峰值 - private final AtomicLong jdbcExecuteTimeNano = new AtomicLong(); + private final AtomicLong jdbcExecuteCount = new AtomicLong(); + private final AtomicLong jdbcExecuteErrorCount = new AtomicLong(); + private final AtomicLong jdbcExecutePeak = new AtomicLong(); // 单次请求执行SQL次数的峰值 + private final AtomicLong jdbcExecuteTimeNano = new AtomicLong(); - private final AtomicLong jdbcCommitCount = new AtomicLong(); - private final AtomicLong jdbcRollbackCount = new AtomicLong(); + private final AtomicLong jdbcCommitCount = new AtomicLong(); + private final AtomicLong jdbcRollbackCount = new AtomicLong(); - private final AtomicLong errorCount = new AtomicLong(); + private final AtomicLong jdbcPoolConnectionOpenCount = new AtomicLong(); + private final AtomicLong jdbcPoolConnectionCloseCount = new AtomicLong(); - private volatile long lastAccessTimeMillis = -1L; + private final AtomicLong jdbcResultSetOpenCount = new AtomicLong(); + private final AtomicLong jdbcResultSetCloseCount = new AtomicLong(); - private final static ThreadLocal currentLocal = new ThreadLocal(); + private final AtomicLong errorCount = new AtomicLong(); + + private volatile long lastAccessTimeMillis = -1L; + + private final static ThreadLocal currentLocal = new ThreadLocal(); public WebURIStat(String uri){ super(); @@ -131,12 +137,13 @@ public class WebURIStat { } } - { - long jdbcExecuteErrorCount = localStat.getJdbcExecuteErrorCount(); - if (jdbcExecuteErrorCount > 0) { - this.jdbcExecuteErrorCount.addAndGet(jdbcExecuteErrorCount); - } - } + this.jdbcExecuteErrorCount.addAndGet(localStat.getJdbcExecuteErrorCount()); + + this.addJdbcPoolConnectionOpenCount(localStat.getJdbcPoolConnectionOpenCount()); + this.addJdbcPoolConnectionCloseCount(localStat.getJdbcPoolConnectionCloseCount()); + + this.addJdbcResultSetOpenCount(localStat.getJdbcResultSetOpenCount()); + this.addJdbcResultSetCloseCount(localStat.getJdbcResultSetCloseCount()); } } @@ -251,6 +258,46 @@ public class WebURIStat { return errorCount.get(); } + public long getJdbcPoolConnectionOpenCount() { + return jdbcPoolConnectionOpenCount.get(); + } + + public void addJdbcPoolConnectionOpenCount(long delta) { + jdbcPoolConnectionOpenCount.addAndGet(delta); + } + + public void incrementJdbcPoolConnectionOpenCount() { + jdbcPoolConnectionOpenCount.incrementAndGet(); + } + + public long getJdbcPoolConnectionCloseCount() { + return jdbcPoolConnectionCloseCount.get(); + } + + public void addJdbcPoolConnectionCloseCount(long delta) { + jdbcPoolConnectionCloseCount.addAndGet(delta); + } + + public void incrementJdbcPoolConnectionCloseCount() { + jdbcPoolConnectionCloseCount.incrementAndGet(); + } + + public long getJdbcResultSetOpenCount() { + return jdbcResultSetOpenCount.get(); + } + + public void addJdbcResultSetOpenCount(long delta) { + jdbcResultSetOpenCount.addAndGet(delta); + } + + public long getJdbcResultSetCloseCount() { + return jdbcResultSetCloseCount.get(); + } + + public void addJdbcResultSetCloseCount(long delta) { + jdbcResultSetCloseCount.addAndGet(delta); + } + public Map getStatData() { Map data = new LinkedHashMap(); @@ -276,6 +323,12 @@ public class WebURIStat { data.put("JdbcUpdateCount", this.getJdbcUpdateCount()); data.put("JdbcUpdatePeak", this.getJdbcUpdatePeak()); + data.put("JdbcPoolConnectionOpenCount", this.getJdbcPoolConnectionOpenCount()); + data.put("JdbcPoolConnectionCloseCount", this.getJdbcPoolConnectionCloseCount()); + + data.put("JdbcResultSetOpenCount", this.getJdbcResultSetOpenCount()); + data.put("JdbcResultSetCloseCount", this.getJdbcResultSetCloseCount()); + return data; } } diff --git a/src/main/java/com/alibaba/druid/support/spring/stat/SpringMethodStat.java b/src/main/java/com/alibaba/druid/support/spring/stat/SpringMethodStat.java index 01aa877314..ec30e53ccd 100644 --- a/src/main/java/com/alibaba/druid/support/spring/stat/SpringMethodStat.java +++ b/src/main/java/com/alibaba/druid/support/spring/stat/SpringMethodStat.java @@ -1,5 +1,6 @@ package com.alibaba.druid.support.spring.stat; +import java.util.Date; import java.util.LinkedHashMap; import java.util.Map; import java.util.concurrent.atomic.AtomicInteger; @@ -26,6 +27,12 @@ public class SpringMethodStat { private final AtomicLong jdbcCommitCount = new AtomicLong(); private final AtomicLong jdbcRollbackCount = new AtomicLong(); + private final AtomicLong jdbcPoolConnectionOpenCount = new AtomicLong(); + private final AtomicLong jdbcPoolConnectionCloseCount = new AtomicLong(); + + private volatile Throwable lastError; + private volatile long lastErrorTimeMillis; + public SpringMethodStat(SpringMethodInfo methodInfo){ this.methodInfo = methodInfo; } @@ -39,10 +46,17 @@ public class SpringMethodStat { jdbcFetchRowCount.set(0); jdbcUpdateCount.set(0); jdbcExecuteCount.set(0); + jdbcExecuteErrorCount.set(0); jdbcExecuteTimeNano.set(0); jdbcCommitCount.set(0); jdbcRollbackCount.set(0); + + jdbcPoolConnectionOpenCount.set(0); + jdbcPoolConnectionCloseCount.set(0); + + lastError = null; + lastErrorTimeMillis = 0; } public SpringMethodInfo getMethodInfo() { @@ -84,9 +98,27 @@ public class SpringMethodStat { if (error != null) { executeErrorCount.incrementAndGet(); + lastError = error; + lastErrorTimeMillis = System.currentTimeMillis(); } } + public Throwable getLastError() { + return lastError; + } + + public Date getLastErrorTime() { + if (lastErrorTimeMillis <= 0) { + return null; + } + + return new Date(lastErrorTimeMillis); + } + + public long getLastErrorTimeMillis() { + return lastErrorTimeMillis; + } + public int getRunningCount() { return this.runningCount.get(); } @@ -138,15 +170,15 @@ public class SpringMethodStat { public long getJdbcExecuteCount() { return jdbcExecuteCount.get(); } - + public long getJdbcExecuteErrorCount() { return jdbcExecuteErrorCount.get(); } - + public void addJdbcExecuteErrorCount(long executeCount) { jdbcExecuteErrorCount.addAndGet(executeCount); } - + public void incrementJdbcExecuteErrorCount() { jdbcExecuteErrorCount.incrementAndGet(); } @@ -187,6 +219,30 @@ public class SpringMethodStat { this.jdbcRollbackCount.addAndGet(rollbackCount); } + public long getJdbcPoolConnectionOpenCount() { + return jdbcPoolConnectionOpenCount.get(); + } + + public void addJdbcPoolConnectionOpenCount(long delta) { + jdbcPoolConnectionOpenCount.addAndGet(delta); + } + + public void incrementJdbcPoolConnectionOpenCount() { + jdbcPoolConnectionOpenCount.incrementAndGet(); + } + + public long getJdbcPoolConnectionCloseCount() { + return jdbcPoolConnectionCloseCount.get(); + } + + public void addJdbcPoolConnectionCloseCount(long delta) { + jdbcPoolConnectionCloseCount.addAndGet(delta); + } + + public void incrementJdbcPoolConnectionCloseCount() { + jdbcPoolConnectionCloseCount.incrementAndGet(); + } + public Map getStatData() { Map data = new LinkedHashMap(); @@ -202,12 +258,18 @@ public class SpringMethodStat { data.put("JdbcCommitCount", this.getJdbcCommitCount()); data.put("JdbcRollbackCount", this.getJdbcRollbackCount()); + data.put("JdbcPoolConnectionOpenCount", this.getJdbcPoolConnectionOpenCount()); + data.put("JdbcPoolConnectionCloseCount", this.getJdbcPoolConnectionCloseCount()); + data.put("JdbcExecuteCount", this.getJdbcExecuteCount()); data.put("JdbcExecuteErrorCount", this.getJdbcExecuteErrorCount()); data.put("JdbcExecuteTimeMillis", this.getJdbcExecuteTimeMillis()); data.put("JdbcFetchRowCount", this.getJdbcFetchRowCount()); data.put("JdbcUpdateCount", this.getJdbcUpdateCount()); + data.put("LastError", this.getLastError()); + data.put("LastErrorTime", this.getLastErrorTime()); + return data; } } diff --git a/src/main/resources/support/http/resources/js/weburi-detail.js b/src/main/resources/support/http/resources/js/weburi-detail.js index d7a68c5744..0d3ff1c632 100644 --- a/src/main/resources/support/http/resources/js/weburi-detail.js +++ b/src/main/resources/support/http/resources/js/weburi-detail.js @@ -25,4 +25,8 @@ function ajaxResponseForSqlInfo() { changeInnerHtml("JdbcFetchRowPeak", stat.JdbcFetchRowPeak); changeInnerHtml("JdbcUpdateCount", stat.JdbcUpdateCount); changeInnerHtml("JdbcUpdatePeak", stat.JdbcUpdatePeak); + changeInnerHtml("JdbcPoolConnectionOpenCount", stat.JdbcPoolConnectionOpenCount); + changeInnerHtml("JdbcPoolConnectionCloseCount", stat.JdbcPoolConnectionCloseCount); + changeInnerHtml("JdbcResultSetOpenCount", stat.JdbcResultSetOpenCount); + changeInnerHtml("JdbcResultSetCloseCount", stat.JdbcResultSetCloseCount); } diff --git a/src/main/resources/support/http/resources/weburi-detail.html b/src/main/resources/support/http/resources/weburi-detail.html index 49f6d74fb6..6411af33e5 100644 --- a/src/main/resources/support/http/resources/weburi-detail.html +++ b/src/main/resources/support/http/resources/weburi-detail.html @@ -85,6 +85,22 @@ JdbcUpdatePeak + + JdbcPoolConnectionOpenCount + + + + JdbcPoolConnectionCloseCount + + + + JdbcResultSetOpenCount + + + + JdbcResultSetCloseCount + +