From 848838e55ca323736c829190a30d1e6eef4f42ec Mon Sep 17 00:00:00 2001 From: wenshao Date: Sun, 19 Aug 2012 08:01:58 +0800 Subject: [PATCH] improve springStat --- .../druid/support/JSONDruidStatService.java | 10 +++ .../druid/support/http/WebStatFilter.java | 3 + .../support/spring/stat/SpringMethodStat.java | 48 +++++++---- .../druid/support/spring/stat/SpringStat.java | 11 +++ .../spring/stat/SpringStatManager.java | 13 +++ .../support/spring/stat/SpringStatUtils.java | 16 ++++ .../http/resources/js/spring-detail.js | 27 ++++++ .../support/http/resources/js/spring.js | 33 ++++---- .../support/http/resources/spring-detail.html | 84 +++++++++++++++++++ .../alibaba/druid/benckmark/pool/Case1.java | 6 +- 10 files changed, 215 insertions(+), 36 deletions(-) create mode 100644 src/main/resources/support/http/resources/js/spring-detail.js create mode 100644 src/main/resources/support/http/resources/spring-detail.html diff --git a/src/main/java/com/alibaba/druid/support/JSONDruidStatService.java b/src/main/java/com/alibaba/druid/support/JSONDruidStatService.java index bf5d329999..c7af7acb78 100644 --- a/src/main/java/com/alibaba/druid/support/JSONDruidStatService.java +++ b/src/main/java/com/alibaba/druid/support/JSONDruidStatService.java @@ -118,6 +118,12 @@ public class JSONDruidStatService { if (url.startsWith("/spring.json")) { return returnJSONResult(RESULT_CODE_SUCCESS, getSpringStatDataList(parameters)); } + + if (url.startsWith("/spring-detail.json")) { + String clazz = parameters.get("class"); + String method = parameters.get("method"); + return returnJSONResult(RESULT_CODE_SUCCESS, getSpringMethodStatData(clazz, method)); + } return returnJSONResult(RESULT_CODE_ERROR, "Do not support this request, please contact with administrator."); } @@ -139,6 +145,10 @@ public class JSONDruidStatService { private Map getWebSessionStatData(String sessionId) { return WebAppStatManager.getInstance().getSessionStat(sessionId); } + + private Map getSpringMethodStatData(String clazz, String method) { + return SpringStatManager.getInstance().getMethodStatData(clazz, method); + } private List> getWebSessionStatDataList(Map parameters) { List> array = WebAppStatManager.getInstance().getSessionStatData(); 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 fb4ad724bd..12667b6f1b 100644 --- a/src/main/java/com/alibaba/druid/support/http/WebStatFilter.java +++ b/src/main/java/com/alibaba/druid/support/http/WebStatFilter.java @@ -421,6 +421,9 @@ public class WebStatFilter implements Filter { SpringMethodStat springMethodStat = SpringMethodStat.current(); if (springMethodStat != null) { springMethodStat.addJdbcExecuteTimeNano(nanos); + if (error != null) { + springMethodStat.incrementJdbcExecuteErrorCount(); + } } } 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 f76a72057b..01aa877314 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 @@ -7,39 +7,40 @@ import java.util.concurrent.atomic.AtomicLong; public class SpringMethodStat { - private final static ThreadLocal currentLocal = new ThreadLocal(); + private final static ThreadLocal currentLocal = new ThreadLocal(); - private final SpringMethodInfo methodInfo; + private final SpringMethodInfo methodInfo; - private final AtomicInteger runningCount = new AtomicInteger(); - private final AtomicInteger concurrentMax = new AtomicInteger(); - private final AtomicLong executeCount = new AtomicLong(0); - private final AtomicLong executeErrorCount = new AtomicLong(0); - private final AtomicLong executeTimeNano = new AtomicLong(); + private final AtomicInteger runningCount = new AtomicInteger(); + private final AtomicInteger concurrentMax = new AtomicInteger(); + private final AtomicLong executeCount = new AtomicLong(0); + private final AtomicLong executeErrorCount = new AtomicLong(0); + private final AtomicLong executeTimeNano = new AtomicLong(); - private final AtomicLong jdbcFetchRowCount = new AtomicLong(); - private final AtomicLong jdbcUpdateCount = new AtomicLong(); - private final AtomicLong jdbcExecuteCount = new AtomicLong(); - private final AtomicLong jdbcExecuteTimeNano = new AtomicLong(); + private final AtomicLong jdbcFetchRowCount = new AtomicLong(); + private final AtomicLong jdbcUpdateCount = new AtomicLong(); + private final AtomicLong jdbcExecuteCount = new AtomicLong(); + private final AtomicLong jdbcExecuteErrorCount = new AtomicLong(); + 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(); public SpringMethodStat(SpringMethodInfo methodInfo){ this.methodInfo = methodInfo; } - + public void reset() { concurrentMax.set(0); executeCount.set(0); executeErrorCount.set(0); executeTimeNano.set(0); - + jdbcFetchRowCount.set(0); jdbcUpdateCount.set(0); jdbcExecuteCount.set(0); jdbcExecuteTimeNano.set(0); - + jdbcCommitCount.set(0); jdbcRollbackCount.set(0); } @@ -137,6 +138,18 @@ 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(); + } public long getJdbcExecuteTimeMillis() { return getJdbcExecuteTimeNano() / (1000 * 1000); @@ -176,7 +189,7 @@ public class SpringMethodStat { public Map getStatData() { Map data = new LinkedHashMap(); - + data.put("Class", this.getMethodInfo().getClassName()); data.put("Method", this.getMethodInfo().getSignature()); @@ -190,6 +203,7 @@ public class SpringMethodStat { data.put("JdbcRollbackCount", this.getJdbcRollbackCount()); 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()); diff --git a/src/main/java/com/alibaba/druid/support/spring/stat/SpringStat.java b/src/main/java/com/alibaba/druid/support/spring/stat/SpringStat.java index 1eaddd2aca..f983a66c6d 100644 --- a/src/main/java/com/alibaba/druid/support/spring/stat/SpringStat.java +++ b/src/main/java/com/alibaba/druid/support/spring/stat/SpringStat.java @@ -50,4 +50,15 @@ public class SpringStat { } return methodStatDataList; } + + public Map getMethodStatData(String clazz, String method) { + for (SpringMethodStat methodStat : this.methodStats.values()) { + SpringMethodInfo methodInfo = methodStat.getMethodInfo(); + if (methodInfo.getClassName().equals(clazz) && methodInfo.getSignature().equals(method)) { + return methodStat.getStatData(); + } + } + + return null; + } } diff --git a/src/main/java/com/alibaba/druid/support/spring/stat/SpringStatManager.java b/src/main/java/com/alibaba/druid/support/spring/stat/SpringStatManager.java index 986d9e84f0..7b477ad047 100644 --- a/src/main/java/com/alibaba/druid/support/spring/stat/SpringStatManager.java +++ b/src/main/java/com/alibaba/druid/support/spring/stat/SpringStatManager.java @@ -63,6 +63,19 @@ public class SpringStatManager { return allMethodStatDataList; } + public Map getMethodStatData(String clazz, String method) { + Set stats = getSpringStatSet(); + + for (Object stat : stats) { + Map statData = SpringStatUtils.getMethodStatData(stat, clazz, method); + if (statData != null) { + return statData; + } + } + + return null; + } + public void resetStat() { Set stats = getSpringStatSet(); diff --git a/src/main/java/com/alibaba/druid/support/spring/stat/SpringStatUtils.java b/src/main/java/com/alibaba/druid/support/spring/stat/SpringStatUtils.java index 128a6cc159..c38296ee5b 100644 --- a/src/main/java/com/alibaba/druid/support/spring/stat/SpringStatUtils.java +++ b/src/main/java/com/alibaba/druid/support/spring/stat/SpringStatUtils.java @@ -26,6 +26,22 @@ public class SpringStatUtils { return null; } } + + @SuppressWarnings("unchecked") + public static Map getMethodStatData(Object methodStat, String clazz, String methodSignature) { + if (methodStat.getClass() == SpringStat.class) { + return ((SpringStat) methodStat).getMethodStatData(clazz, methodSignature); + } + + try { + Method method = methodStat.getClass().getMethod("getMethodStatData", String.class, String.class); + Object obj = method.invoke(methodStat, clazz, methodSignature); + return (Map) obj; + } catch (Exception e) { + LOG.error("getMethodStatDataList error", e); + return null; + } + } public static void reset(Object webStat) { if (webStat.getClass() == SpringStat.class) { diff --git a/src/main/resources/support/http/resources/js/spring-detail.js b/src/main/resources/support/http/resources/js/spring-detail.js new file mode 100644 index 0000000000..7dd99c5383 --- /dev/null +++ b/src/main/resources/support/http/resources/js/spring-detail.js @@ -0,0 +1,27 @@ +function ajaxRequestForSqlInfo() { + var clazz = getUrlVar("class"); + var method = getUrlVar("method"); + xmlHttpForConnectionInfo = getRequestObject(); + sendRequest(xmlHttpForConnectionInfo, 'spring-detail.json?class=' + clazz + '&method=' + method, ajaxResponseForSqlInfo) +} + +function ajaxResponseForSqlInfo() { + var stat = getJSONResponseContent(xmlHttpForConnectionInfo); + if (stat == null) + return; + + changeInnerHtml("Class", stat.Class); + changeInnerHtml("Method", stat.Method); + changeInnerHtml("ExecuteCount", stat.ExecuteCount); + changeInnerHtml("ExecuteErrorCount", stat.ExecuteErrorCount); + changeInnerHtml("ExecuteTimeMillis", stat.ExecuteTimeMillis); + changeInnerHtml("RunningCount", stat.RunningCount); + changeInnerHtml("ConcurrentMax", stat.ConcurrentMax); + changeInnerHtml("JdbcExecuteCount", stat.JdbcExecuteCount); + changeInnerHtml("JdbcExecuteErrorCount", stat.JdbcExecuteErrorCount); + changeInnerHtml("JdbcExecuteTimeMillis", stat.JdbcExecuteTimeMillis); + changeInnerHtml("JdbcCommitCount", stat.JdbcCommitCount); + changeInnerHtml("JdbcRollbackCount", stat.JdbcRollbackCount); + changeInnerHtml("JdbcFetchRowCount", stat.JdbcFetchRowCount); + changeInnerHtml("JdbcUpdateCount", stat.JdbcUpdateCount); +} diff --git a/src/main/resources/support/http/resources/js/spring.js b/src/main/resources/support/http/resources/js/spring.js index b67137770c..8519eeb288 100644 --- a/src/main/resources/support/http/resources/js/spring.js +++ b/src/main/resources/support/http/resources/js/spring.js @@ -85,28 +85,29 @@ function subSqlString(sql, len) { return sql.substr(0, len) + '...'; } function ajaxResponseForDataSourceSqlStatInfo() { - var sqlStatList = getJSONResponseContent(xmlHttpForDataSourceSqlStatInfo); - if(sqlStatList==null) return; + var statList = getJSONResponseContent(xmlHttpForDataSourceSqlStatInfo); + if(statList==null) return; var sqlStatTable = document.getElementById("SpringStatTable"); while (sqlStatTable.rows.length > 1) { sqlStatTable.deleteRow(1); } - for ( var i = 0; i < sqlStatList.length; i++) { - var sqlStat = sqlStatList[i]; + for ( var i = 0; i < statList.length; i++) { + var stat = statList[i]; var newRow = sqlStatTable.insertRow(-1); newRow.insertCell(-1).innerHTML = i+1; - newRow.insertCell(-1).innerHTML = sqlStat.Class; - newRow.insertCell(-1).innerHTML = sqlStat.Method; - newRow.insertCell(-1).innerHTML = sqlStat.ExecuteCount; - newRow.insertCell(-1).innerHTML = sqlStat.ExecuteTimeMillis; - newRow.insertCell(-1).innerHTML = sqlStat.RunningCount; - newRow.insertCell(-1).innerHTML = sqlStat.ConcurrentMax; - newRow.insertCell(-1).innerHTML = sqlStat.JdbcExecuteCount; - newRow.insertCell(-1).innerHTML = sqlStat.JdbcExecuteTimeMillis; - newRow.insertCell(-1).innerHTML = sqlStat.JdbcCommitCount; - newRow.insertCell(-1).innerHTML = sqlStat.JdbcRollbackCount; - newRow.insertCell(-1).innerHTML = sqlStat.JdbcFetchRowCount; - newRow.insertCell(-1).innerHTML = sqlStat.JdbcUpdateCount; + newRow.insertCell(-1).innerHTML = stat.Class; + newRow.insertCell(-1).innerHTML = '' + stat.Method + ''; + + newRow.insertCell(-1).innerHTML = stat.ExecuteCount; + newRow.insertCell(-1).innerHTML = stat.ExecuteTimeMillis; + newRow.insertCell(-1).innerHTML = stat.RunningCount; + newRow.insertCell(-1).innerHTML = stat.ConcurrentMax; + newRow.insertCell(-1).innerHTML = stat.JdbcExecuteCount; + newRow.insertCell(-1).innerHTML = stat.JdbcExecuteTimeMillis; + newRow.insertCell(-1).innerHTML = stat.JdbcCommitCount; + newRow.insertCell(-1).innerHTML = stat.JdbcRollbackCount; + newRow.insertCell(-1).innerHTML = stat.JdbcFetchRowCount; + newRow.insertCell(-1).innerHTML = stat.JdbcUpdateCount; } } diff --git a/src/main/resources/support/http/resources/spring-detail.html b/src/main/resources/support/http/resources/spring-detail.html new file mode 100644 index 0000000000..671e5629e0 --- /dev/null +++ b/src/main/resources/support/http/resources/spring-detail.html @@ -0,0 +1,84 @@ + + + + Druid Spring Stat + + + + + + + +
+
+

Spring View

+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Class
Method
ExecuteCount
ExecuteErrorCount
ExecuteTimeMillis
RunningCount
ConcurrentMax
JdbcExecuteCount
JdbcExecuteErrorCount
JdbcExecuteTimeMillis
JdbcCommitCount
JdbcRollbackCount
JdbcFetchRowCount
JdbcUpdateCount
+
+
+ + diff --git a/src/test/java/com/alibaba/druid/benckmark/pool/Case1.java b/src/test/java/com/alibaba/druid/benckmark/pool/Case1.java index 81b187093a..fa851a30c2 100644 --- a/src/test/java/com/alibaba/druid/benckmark/pool/Case1.java +++ b/src/test/java/com/alibaba/druid/benckmark/pool/Case1.java @@ -45,9 +45,9 @@ public class Case1 extends TestCase { private int maxPoolSize = 50; private int maxActive = 50; private String validationQuery = "SELECT 1"; - private int threadCount = 40; + private int threadCount = 2; private int loopCount = 4; - final int LOOP_COUNT = 1000 * 100; + final int LOOP_COUNT = 1000 * 1000; protected void setUp() throws Exception { jdbcUrl = "jdbc:fake:dragoon_v25masterdb"; @@ -100,7 +100,7 @@ public class Case1 extends TestCase { System.out.println(); } - public void f_test_2() throws Exception { + public void test_2() throws Exception { BoneCPDataSource dataSource = new BoneCPDataSource(); // dataSource.(10); // dataSource.setMaxActive(50);