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 11ffc8a8ff..fb4ad724bd 100644 --- a/src/main/java/com/alibaba/druid/support/http/WebStatFilter.java +++ b/src/main/java/com/alibaba/druid/support/http/WebStatFilter.java @@ -87,7 +87,7 @@ public class WebStatFilter implements Filter { WebRequestStat requestStat = new WebRequestStat(startNano, startMillis); WebRequestStat.set(requestStat); - + WebSessionStat sessionStat = getSessionStat(httpRequest); webAppStat.beforeInvoke(); @@ -413,6 +413,9 @@ public class WebStatFilter implements Filter { WebRequestStat reqStat = WebRequestStat.current(); if (reqStat != null) { reqStat.addJdbcExecuteTimeNano(nanos); + if (error != null) { + reqStat.incrementJdbcExecuteErrorCount(); + } } SpringMethodStat springMethodStat = SpringMethodStat.current(); 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 dab15a12fe..071ab42ed7 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 @@ -11,6 +11,7 @@ public class WebRequestStat { private long jdbcUpdateCount; private long jdbcFetchRowCount; private long jdbcExecuteNano; + private long jdbcExecuteErrorCount; public WebRequestStat(){ @@ -19,7 +20,7 @@ public class WebRequestStat { public WebRequestStat(long startNano){ this.startNano = startNano; } - + public WebRequestStat(long startNano, long startMillis){ this.startNano = startNano; this.startMillis = startMillis; @@ -107,4 +108,11 @@ public class WebRequestStat { this.jdbcRollbackCount++; } + public long getJdbcExecuteErrorCount() { + return jdbcExecuteErrorCount; + } + + public void incrementJdbcExecuteErrorCount() { + jdbcExecuteErrorCount++; + } } diff --git a/src/main/java/com/alibaba/druid/support/http/stat/WebSessionStat.java b/src/main/java/com/alibaba/druid/support/http/stat/WebSessionStat.java index 7b0a5ef8ea..611bd6c4d1 100644 --- a/src/main/java/com/alibaba/druid/support/http/stat/WebSessionStat.java +++ b/src/main/java/com/alibaba/druid/support/http/stat/WebSessionStat.java @@ -104,7 +104,7 @@ public class WebSessionStat { } public Date getLastAccessTime() { - if (lastAccessTimeMillis == -1L) { + if (lastAccessTimeMillis < 0L) { return null; } 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 f28fc811f1..8e1b4f9adc 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 @@ -1,5 +1,6 @@ package com.alibaba.druid.support.http.stat; +import java.util.Date; import java.util.LinkedHashMap; import java.util.Map; import java.util.concurrent.atomic.AtomicInteger; @@ -9,25 +10,30 @@ 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 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 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(); @@ -61,12 +67,21 @@ public class WebURIStat { } requestCount.incrementAndGet(); + + WebRequestStat requestStat = WebRequestStat.current(); + if (requestStat != null) { + this.setLastAccessTimeMillis(requestStat.getStartMillis()); + } } public void afterInvoke(Throwable error, long nanos) { runningCount.decrementAndGet(); requestTimeNano.addAndGet(nanos); + if (error != null) { + errorCount.incrementAndGet(); + } + { WebRequestStat localStat = WebRequestStat.current(); if (localStat != null) { @@ -115,6 +130,13 @@ public class WebURIStat { } } } + + { + long jdbcExecuteErrorCount = localStat.getJdbcExecuteErrorCount(); + if (jdbcExecuteErrorCount > 0) { + this.jdbcExecuteErrorCount.addAndGet(jdbcExecuteErrorCount); + } + } } } @@ -168,7 +190,7 @@ public class WebURIStat { public void incrementJdbcExecuteCount() { jdbcExecuteCount.incrementAndGet(); } - + public void addJdbcExecuteCount(long executeCount) { jdbcExecuteCount.addAndGet(executeCount); } @@ -177,6 +199,10 @@ public class WebURIStat { return jdbcExecuteCount.get(); } + public AtomicLong getJdbcExecuteErrorCount() { + return jdbcExecuteErrorCount; + } + public long getJdbcExecutePeak() { return jdbcExecutePeak.get(); } @@ -205,6 +231,26 @@ public class WebURIStat { return jdbcRollbackCount.get(); } + public void setLastAccessTimeMillis(long lastAccessTimeMillis) { + this.lastAccessTimeMillis = lastAccessTimeMillis; + } + + public Date getLastAccessTime() { + if (lastAccessTimeMillis < 0L) { + return null; + } + + return new Date(lastAccessTimeMillis); + } + + public long getLastAccessTimeMillis() { + return lastAccessTimeMillis; + } + + public long getErrorCount() { + return errorCount.get(); + } + public Map getStatData() { Map data = new LinkedHashMap(); @@ -213,11 +259,14 @@ public class WebURIStat { data.put("ConcurrentMax", this.getConcurrentMax()); data.put("RequestCount", this.getRequestCount()); data.put("RequestTimeMillis", this.getRequestTimeMillis()); + data.put("ErrorCount", this.getErrorCount()); + data.put("LastAccessTime", this.getLastAccessTime()); data.put("JdbcCommitCount", this.getJdbcCommitCount()); data.put("JdbcRollbackCount", this.getJdbcRollbackCount()); data.put("JdbcExecuteCount", this.getJdbcExecuteCount()); + data.put("JdbcExecuteErrorCount", this.getJdbcExecuteErrorCount()); data.put("JdbcExecutePeak", this.getJdbcExecutePeak()); data.put("JdbcExecuteTimeMillis", this.getJdbcExecuteTimeMillis()); diff --git a/src/main/resources/support/http/resources/js/sql.js b/src/main/resources/support/http/resources/js/sql.js index bf1e7f1742..ebec28cb7c 100644 --- a/src/main/resources/support/http/resources/js/sql.js +++ b/src/main/resources/support/http/resources/js/sql.js @@ -109,8 +109,8 @@ function ajaxResponseForDataSourceSqlStatInfo() { newRow.insertCell(-1).innerHTML = sqlStat.TotalTime; //显示执行的时间比配置的均值时间慢的SQL链接 var lastSlowHtml = sqlStat.MaxTimespan; - if(sqlStat.LastSlowParameters!=null&&sqlStat.LastSlowParameters.length>0){ - lastSlowHtml =''+sqlStat.MaxTimespan+''; + if (sqlStat.LastSlowParameters!=null && sqlStat.LastSlowParameters.length>0) { + lastSlowHtml =''+sqlStat.MaxTimespan+''; } newRow.insertCell(-1).innerHTML = lastSlowHtml; newRow.insertCell(-1).innerHTML = sqlStat.InTransactionCount; 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 a0d939f487..d7a68c5744 100644 --- a/src/main/resources/support/http/resources/js/weburi-detail.js +++ b/src/main/resources/support/http/resources/js/weburi-detail.js @@ -12,9 +12,11 @@ function ajaxResponseForSqlInfo() { changeInnerHtml("URI", stat.URI); changeInnerHtml("RequestCount", stat.RequestCount); changeInnerHtml("RequestTimeMillis", stat.RequestTimeMillis); + changeInnerHtml("LastAccessTime", stat.LastAccessTime); changeInnerHtml("RunningCount", stat.RunningCount); changeInnerHtml("ConcurrentMax", stat.ConcurrentMax); changeInnerHtml("JdbcExecuteCount", stat.JdbcExecuteCount); + changeInnerHtml("JdbcExecuteErrorCount", stat.JdbcExecuteErrorCount); changeInnerHtml("JdbcExecutePeak", stat.JdbcExecutePeak); changeInnerHtml("JdbcExecuteTimeMillis", stat.JdbcExecuteTimeMillis); changeInnerHtml("JdbcCommitCount", stat.JdbcCommitCount); diff --git a/src/main/resources/support/http/resources/weburi-detail.html b/src/main/resources/support/http/resources/weburi-detail.html index 3dc4747d80..49f6d74fb6 100644 --- a/src/main/resources/support/http/resources/weburi-detail.html +++ b/src/main/resources/support/http/resources/weburi-detail.html @@ -33,6 +33,10 @@ RequestTimeMillis + + LastAccessTime + + RunningCount @@ -45,6 +49,10 @@ JdbcExecuteCount + + JdbcExecuteErrorCount + + JdbcExecutePeak