From b679c084e42fc1ccc367a84ad01c6ac29d37f497 Mon Sep 17 00:00:00 2001 From: wenshao Date: Sun, 12 Aug 2012 19:41:07 +0800 Subject: [PATCH] add WebSessionStat support --- .../druid/support/JSONDruidStatService.java | 2 +- .../druid/support/http/WebStatFilter.java | 38 +++++- .../druid/support/http/stat/WebAppStat.java | 4 +- .../support/http/stat/WebRequestStat.java | 9 ++ .../support/http/stat/WebSessionStat.java | 117 ++++++++++++++++-- .../support/http/resources/js/websession.js | 4 + .../support/http/resources/websession.html | 4 + 7 files changed, 163 insertions(+), 15 deletions(-) diff --git a/src/main/java/com/alibaba/druid/support/JSONDruidStatService.java b/src/main/java/com/alibaba/druid/support/JSONDruidStatService.java index d88e0158e9..92a73bff94 100644 --- a/src/main/java/com/alibaba/druid/support/JSONDruidStatService.java +++ b/src/main/java/com/alibaba/druid/support/JSONDruidStatService.java @@ -159,7 +159,7 @@ public class JSONDruidStatService { Map dataMap = new LinkedHashMap(); dataMap.put("ResultCode", resultCode); dataMap.put("Content", content); - return JSON.toJSONString(dataMap); + return JSON.toJSONStringWithDateFormat(dataMap, "yyyy-MM-dd hh:mm:ss"); } } 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 ba228da431..589b972d40 100644 --- a/src/main/java/com/alibaba/druid/support/http/WebStatFilter.java +++ b/src/main/java/com/alibaba/druid/support/http/WebStatFilter.java @@ -18,9 +18,14 @@ import com.alibaba.druid.support.http.stat.WebAppStatManager; import com.alibaba.druid.support.http.stat.WebRequestStat; import com.alibaba.druid.support.http.stat.WebSessionStat; import com.alibaba.druid.support.http.stat.WebURIStat; +import com.alibaba.druid.support.logging.Log; +import com.alibaba.druid.support.logging.LogFactory; +import com.alibaba.druid.util.DruidWebUtils; public class WebStatFilter implements Filter { + private final static Log LOG = LogFactory.getLog(WebStatFilter.class); + private WebAppStat webAppStat = null; private WebStatFilterContextListener statFilterContextListener = new WebStatFilterContextListener(); @@ -39,6 +44,7 @@ public class WebStatFilter implements Filter { } long startNano = System.nanoTime(); + long startMillis = System.currentTimeMillis(); WebRequestStat requestStat = new WebRequestStat(startNano); WebRequestStat.set(requestStat); @@ -48,6 +54,7 @@ public class WebStatFilter implements Filter { // 第一次访问时,sessionId为null,如果缺省sessionCreate=false,sessionStat就为null。 if (sessionStat != null) { sessionStat.beforeInvoke(); + sessionStat.setLastAccessTimeMillis(startMillis); } try { @@ -64,6 +71,7 @@ public class WebStatFilter implements Filter { } else { sessionStat = getSessionStat(httpRequest); if (sessionStat != null) { + sessionStat.setLastAccessTimeMillis(startMillis); sessionStat.reacord(nanoSpan); } } @@ -72,13 +80,35 @@ public class WebStatFilter implements Filter { } } - public WebSessionStat getSessionStat(HttpServletRequest httpRequest) { + public WebSessionStat getSessionStat(HttpServletRequest request) { WebSessionStat sessionStat = null; - String sessionId = getSessionId(httpRequest); + String sessionId = getSessionId(request); if (sessionId != null) { sessionStat = webAppStat.getSessionStat(sessionId); } + if (sessionStat != null) { + if (sessionStat.getCreateTimeMillis() == -1L) { + HttpSession session = request.getSession(false); + if (session != null) { + sessionStat.setCreateTimeMillis(session.getCreationTime()); + } else { + sessionStat.setCreateTimeMillis(System.currentTimeMillis()); + } + } + + String ip = DruidWebUtils.getRemoteAddr(request); + + int addressCount = sessionStat.getRemoteAddresses().size(); + if (addressCount < 10) { + sessionStat.addRemoteAddress(ip); + } else { + if (!sessionStat.getRemoteAddress().contains(ip)) { + LOG.error("sessoin ip change too many"); + } + } + } + return sessionStat; } @@ -174,6 +204,10 @@ public class WebStatFilter implements Filter { @Override public void executeAfter(String sql, long nanoSpan, Throwable error) { + WebRequestStat localStat = WebRequestStat.current(); + if (localStat != null) { + localStat.addJdbcExecuteNano(nanoSpan); + } } @Override diff --git a/src/main/java/com/alibaba/druid/support/http/stat/WebAppStat.java b/src/main/java/com/alibaba/druid/support/http/stat/WebAppStat.java index f8101927cd..f9d9611525 100644 --- a/src/main/java/com/alibaba/druid/support/http/stat/WebAppStat.java +++ b/src/main/java/com/alibaba/druid/support/http/stat/WebAppStat.java @@ -114,7 +114,9 @@ public class WebAppStat { WebSessionStat uriStat = sessionStatMap.get(sessionId); if (uriStat == null) { - sessionStatMap.putIfAbsent(sessionId, new WebSessionStat(sessionId)); + WebSessionStat newStat = new WebSessionStat(sessionId); + + sessionStatMap.putIfAbsent(sessionId, newStat); uriStat = sessionStatMap.get(sessionId); } 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 a9f67c9f67..17f89e313d 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 @@ -9,6 +9,7 @@ public class WebRequestStat { private long jdbcExecuteCount; private long jdbcUpdateCount; private long jdbcFetchRowCount; + private long jdbcExecuteNano; public WebRequestStat(){ @@ -60,6 +61,14 @@ public class WebRequestStat { return jdbcExecuteCount; } + public long getJdbcExecuteNano() { + return jdbcExecuteNano; + } + + public void addJdbcExecuteNano(long nano) { + jdbcExecuteNano += nano; + } + public long getJdbcUpdateCount() { return jdbcUpdateCount; } 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 665efc9462..8b0e76b558 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 @@ -1,7 +1,10 @@ package com.alibaba.druid.support.http.stat; +import java.util.Date; +import java.util.HashSet; import java.util.LinkedHashMap; import java.util.Map; +import java.util.Set; import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.atomic.AtomicLong; @@ -9,18 +12,24 @@ public class WebSessionStat { private final String sessionId; - private final AtomicInteger runningCount = new AtomicInteger(); - private final AtomicInteger concurrentMax = new AtomicInteger(); - private final AtomicLong requestCount = new AtomicLong(0); + private final AtomicInteger runningCount = new AtomicInteger(); + private final AtomicInteger concurrentMax = new AtomicInteger(); + private final AtomicLong requestCount = new AtomicLong(0); - private final AtomicLong jdbcFetchRowCount = new AtomicLong(); - private final AtomicLong jdbcUpdateCount = new AtomicLong(); - private final AtomicLong jdbcExecuteCount = 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 jdbcCommitCount = new AtomicLong(); - private final AtomicLong jdbcRollbackCount = new AtomicLong(); + private final AtomicLong jdbcCommitCount = new AtomicLong(); + private final AtomicLong jdbcRollbackCount = new AtomicLong(); - private final AtomicLong requestTimeNano = new AtomicLong(); + private final AtomicLong requestTimeNano = new AtomicLong(); + + private long createTimeMillis = -1L; + private long lastAccessTimeMillis = -1L; + + private Set remoteAddresses = new HashSet(); public WebSessionStat(String sessionId){ super(); @@ -31,6 +40,62 @@ public class WebSessionStat { return sessionId; } + public long getCreateTimeMillis() { + return createTimeMillis; + } + + public Date getCreateTime() { + if (createTimeMillis == -1L) { + return null; + } + + return new Date(createTimeMillis); + } + + public void setCreateTimeMillis(long createTimeMillis) { + this.createTimeMillis = createTimeMillis; + } + + public long getLastAccessTimeMillis() { + return lastAccessTimeMillis; + } + + public Date getLastAccessTime() { + if (lastAccessTimeMillis == -1L) { + return null; + } + + return new Date(lastAccessTimeMillis); + } + + public Set getRemoteAddresses() { + return remoteAddresses; + } + + public String getRemoteAddress() { + if (remoteAddresses.size() == 0) { + return null; + } + + if (remoteAddresses.size() == 1) { + return remoteAddresses.iterator().next(); + } + + StringBuilder buf = new StringBuilder(); + for (String item : remoteAddresses) { + if (buf.length() != 0) { + buf.append(","); + } + buf.append(item); + } + + return buf.toString(); + } + + public void setLastAccessTimeMillis(long lastAccessTimeMillis) { + this.lastAccessTimeMillis = lastAccessTimeMillis; + } + public void beforeInvoke() { int running = runningCount.incrementAndGet(); @@ -66,9 +131,14 @@ public class WebSessionStat { this.addJdbcUpdateCount(requestStat.getJdbcUpdateCount()); this.addJdbcCommitCount(requestStat.getJdbcCommitCount()); this.addJdbcRollbackCount(requestStat.getJdbcRollbackCount()); + this.addJdbcExecuteTimeNano(requestStat.getJdbcExecuteNano()); } } + public void addRemoteAddress(String ip) { + this.remoteAddresses.add(ip); + } + public int getRunningCount() { return this.runningCount.get(); } @@ -81,6 +151,14 @@ public class WebSessionStat { return requestCount.get(); } + public long getRequestTimeNano() { + return requestTimeNano.get(); + } + + public long getRequestTimeMillis() { + return getRequestTimeNano() / (1000 * 1000); + } + public void addJdbcFetchRowCount(long delta) { this.jdbcFetchRowCount.addAndGet(delta); } @@ -109,6 +187,18 @@ public class WebSessionStat { return jdbcExecuteCount.get(); } + public long getJdbcExecuteTimeMillis() { + return getJdbcExecuteTimeNano() / (1000 * 1000); + } + + public long getJdbcExecuteTimeNano() { + return jdbcExecuteTimeNano.get(); + } + + public void addJdbcExecuteTimeNano(long nano) { + jdbcExecuteTimeNano.addAndGet(nano); + } + public void incrementJdbcCommitCount() { jdbcCommitCount.incrementAndGet(); } @@ -128,11 +218,11 @@ public class WebSessionStat { public long getJdbcRollbackCount() { return jdbcRollbackCount.get(); } - + public void addJdbcRollbackCount(long rollbackCount) { this.jdbcRollbackCount.addAndGet(rollbackCount); } - + public Map getStatData() { Map data = new LinkedHashMap(); @@ -140,11 +230,16 @@ public class WebSessionStat { data.put("RunningCount", this.getRunningCount()); data.put("ConcurrentMax", this.getConcurrentMax()); data.put("RequestCount", this.getRequestCount()); + data.put("RequestTimeMillisTotal", this.getRequestTimeMillis()); + data.put("CreateTime", this.getCreateTime()); + data.put("LastAccessTime", this.getLastAccessTime()); + data.put("RemoteAddress", this.getRemoteAddress()); data.put("JdbcCommitCount", this.getJdbcCommitCount()); data.put("JdbcRollbackCount", this.getJdbcRollbackCount()); data.put("JdbcExecuteCount", this.getJdbcExecuteCount()); + data.put("JdbcExecuteTimeMillis", this.getJdbcExecuteTimeMillis()); data.put("JdbcFetchRowCount", this.getJdbcFetchRowCount()); data.put("JdbcUpdateCount", this.getJdbcUpdateCount()); diff --git a/src/main/resources/support/http/resources/js/websession.js b/src/main/resources/support/http/resources/js/websession.js index 6e201222ea..c4d638a5a6 100644 --- a/src/main/resources/support/http/resources/js/websession.js +++ b/src/main/resources/support/http/resources/js/websession.js @@ -96,10 +96,14 @@ function ajaxResponseForDataSourceSqlStatInfo() { var newRow = sqlStatTable.insertRow(-1); newRow.insertCell(-1).innerHTML = i+1; newRow.insertCell(-1).innerHTML = sqlStat.SESSIONID; + newRow.insertCell(-1).innerHTML = sqlStat.CreateTime; + newRow.insertCell(-1).innerHTML = sqlStat.RemoteAddress; newRow.insertCell(-1).innerHTML = sqlStat.RequestCount; + newRow.insertCell(-1).innerHTML = sqlStat.RequestTimeMillisTotal; 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; diff --git a/src/main/resources/support/http/resources/websession.html b/src/main/resources/support/http/resources/websession.html index 148f0dfde8..3316533342 100644 --- a/src/main/resources/support/http/resources/websession.html +++ b/src/main/resources/support/http/resources/websession.html @@ -25,10 +25,14 @@ N-- SESSIONID + CreateTime + RemoteAddress Request Count + RequestTime Running Count Concurrent Max JdbcExecuteCount + JdbcExecuteTime JdbcCommitCount JdbcRollbackCount JdbcFetchRowCount