add webStat support

This commit is contained in:
wenshao
2012-08-12 12:23:42 +08:00
parent 60808c1292
commit 2a4f5f3098
6 changed files with 354 additions and 8 deletions
@@ -184,7 +184,7 @@ public class StatFilter extends FilterEventAdapter implements StatFilterMBean {
}
}
}
{
String property = properties.getProperty("druid.stat.logSlowSql");
if ("true".equals(property)) {
@@ -439,6 +439,7 @@ public class StatFilter extends FilterEventAdapter implements StatFilterMBean {
sqlStat.incrementExecuteSuccessCount();
for (int updateCount : updateCountArray) {
sqlStat.addUpdateCount(updateCount);
StatFilterContext.getInstance().addUpdateCount(updateCount);
}
sqlStat.decrementRunningCount();
@@ -518,9 +519,10 @@ public class StatFilter extends FilterEventAdapter implements StatFilterMBean {
}
buf.append(']');
sqlStat.setLastSlowParameters(buf.toString());
if (logSlowSql) {
LOG.error("slow sql " + millis + " millis. \n" + statement.getLastExecuteSql() + "\n" + buf.toString());
LOG.error("slow sql " + millis + " millis. \n" + statement.getLastExecuteSql() + "\n"
+ buf.toString());
}
}
}
@@ -564,19 +566,19 @@ public class StatFilter extends FilterEventAdapter implements StatFilterMBean {
long nanoSpan = System.nanoTime() - resultSet.getConstructNano();
int fetchCount = resultSet.getFetchRowCount();
int fetchRowCount = resultSet.getFetchRowCount();
dataSourceStat.getResultSetStat().afterClose(nanoSpan);
dataSourceStat.getResultSetStat().addFetchRowCount(fetchCount);
dataSourceStat.getResultSetStat().addFetchRowCount(fetchRowCount);
dataSourceStat.getResultSetStat().incrementCloseCounter();
StatFilterContext.getInstance().addFetchRowCount(fetchRowCount);
String sql = resultSet.getSql();
if (sql != null) {
JdbcSqlStat sqlStat = resultSet.getSqlStat();
if (sqlStat != null && resultSet.getCloseCount() == 0) {
sqlStat.addFetchRowCount(fetchCount);
sqlStat.addFetchRowCount(fetchRowCount);
long stmtExecuteNano = resultSet.getStatementProxy().getLastExecuteTimeNano();
sqlStat.addResultSetHoldTimeNano(stmtExecuteNano, nanoSpan);
}
@@ -837,4 +839,6 @@ public class StatFilter extends FilterEventAdapter implements StatFilterMBean {
return features;
}
}
}
@@ -0,0 +1,41 @@
package com.alibaba.druid.filter.stat;
import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;
public class StatFilterContext {
private List<StatFilterContextListener> listeners = new CopyOnWriteArrayList<StatFilterContextListener>();
private static final StatFilterContext instance = new StatFilterContext();
public final static StatFilterContext getInstance() {
return instance;
}
public void addContextListener(StatFilterContextListener listener) {
this.listeners.add(listener);
}
public boolean removeContextListener(StatFilterContextListener listener) {
return listeners.remove(listener);
}
public List<StatFilterContextListener> getListeners() {
return listeners;
}
protected void addUpdateCount(int updateCount) {
for (int i = 0; i < listeners.size(); ++i) {
StatFilterContextListener listener = listeners.get(i);
listener.addUpdateCount(updateCount);
}
}
protected void addFetchRowCount(int fetchRowCount) {
for (int i = 0; i < listeners.size(); ++i) {
StatFilterContextListener listener = listeners.get(i);
listener.addFetchRowCount(fetchRowCount);
}
}
}
@@ -0,0 +1,8 @@
package com.alibaba.druid.filter.stat;
public interface StatFilterContextListener {
void addUpdateCount(int updateCount);
void addFetchRowCount(int fetchRowCount);
}
@@ -0,0 +1,87 @@
package com.alibaba.druid.support.http;
import java.io.IOException;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import com.alibaba.druid.filter.stat.StatFilterContext;
import com.alibaba.druid.filter.stat.StatFilterContextListener;
import com.alibaba.druid.support.http.stat.WebAppStat;
import com.alibaba.druid.support.http.stat.WebURIStat;
public class WebStatFilter implements Filter {
private WebAppStat webAppStat = null;
private WebStatFilterContextListener statFilterContextListener = new WebStatFilterContextListener();
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException,
ServletException {
HttpServletRequest httpRequest = (HttpServletRequest) request;
final String requestURI = getRequestURI(httpRequest);
if (isExclusion(requestURI)) {
chain.doFilter(request, response);
return;
}
long startNano = System.nanoTime();
webAppStat.beforeInvoke(requestURI);
try {
chain.doFilter(request, response);
} finally {
long nanoSpan = System.nanoTime() - startNano;
webAppStat.afterInvoke(nanoSpan);
}
}
public boolean isExclusion(String uri) {
return false;
}
public String getRequestURI(HttpServletRequest request) {
return request.getRequestURI();
}
@Override
public void init(FilterConfig config) throws ServletException {
config.getServletContext().getContextPath();
StatFilterContext.getInstance().addContextListener(statFilterContextListener);
webAppStat = new WebAppStat();
}
@Override
public void destroy() {
StatFilterContext.getInstance().removeContextListener(statFilterContextListener);
}
class WebStatFilterContextListener implements StatFilterContextListener {
@Override
public void addUpdateCount(int updateCount) {
WebURIStat stat = WebURIStat.current();
if (stat != null) {
stat.addJdbcUpdateCount(updateCount);
}
}
@Override
public void addFetchRowCount(int fetchRowCount) {
WebURIStat stat = WebURIStat.current();
if (stat != null) {
stat.addJdbcFetchRowCount(fetchRowCount);
}
}
}
}
@@ -0,0 +1,100 @@
package com.alibaba.druid.support.http.stat;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicLong;
import com.alibaba.druid.support.logging.Log;
import com.alibaba.druid.support.logging.LogFactory;
public class WebAppStat {
private final static Log LOG = LogFactory.getLog(WebAppStat.class);
public final static int DEFAULT_MAX_STAT_URI_COUNT = 1000;
private volatile int maxStatUriCount = DEFAULT_MAX_STAT_URI_COUNT;
private final AtomicInteger runningCount = new AtomicInteger();
private final AtomicInteger concurrentMax = new AtomicInteger();
private final AtomicLong count = new AtomicLong(0);
private final static ThreadLocal<WebAppStat> currentLocal = new ThreadLocal<WebAppStat>();
private final ConcurrentMap<String, WebURIStat> uriStatMap = new ConcurrentHashMap<String, WebURIStat>();
private final AtomicLong uriStatMapFullCount = new AtomicLong();
public static WebAppStat current() {
return currentLocal.get();
}
public void beforeInvoke(String uri) {
currentLocal.set(this);
int running = runningCount.incrementAndGet();
for (;;) {
int max = concurrentMax.get();
if (running > max) {
if (concurrentMax.compareAndSet(max, running)) {
break;
} else {
continue;
}
} else {
break;
}
}
count.incrementAndGet();
WebURIStat uriStat = getURIStat(uri);
if (uriStat != null) {
uriStat.beforeInvoke(uri);
}
}
public WebURIStat getURIStat(String uri) {
if (uriStatMap.size() >= this.getMaxStatUriCount()) {
long fullCount = uriStatMapFullCount.getAndIncrement();
if (fullCount == 0) {
LOG.error("urlStatMap is full");
}
return null;
}
WebURIStat uriStat = uriStatMap.get(uri);
if (uriStat == null) {
uriStatMap.putIfAbsent(uri, new WebURIStat(uri));
uriStat = uriStatMap.get(uri);
}
return uriStat;
}
public void afterInvoke(long nanoSpan) {
runningCount.decrementAndGet();
currentLocal.set(null);
WebURIStat uriStat = WebURIStat.current();
if (uriStat != null) {
uriStat.afterInvoke(nanoSpan);
}
}
public int getMaxStatUriCount() {
return maxStatUriCount;
}
public void setMaxStatUriCount(int maxStatUriCount) {
this.maxStatUriCount = maxStatUriCount;
}
}
@@ -0,0 +1,106 @@
package com.alibaba.druid.support.http.stat;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicLong;
public class WebURIStat {
private final String uri;
private final AtomicInteger runningCount = new AtomicInteger();
private final AtomicInteger concurrentMax = new AtomicInteger();
private final AtomicLong count = new AtomicLong(0);
private final AtomicLong jdbcFetchRowCount = new AtomicLong();
private final AtomicLong jdbcFetchRowPeak = new AtomicLong();
private final AtomicLong jdbcUpdateCount = new AtomicLong();
private final AtomicLong jdbcExecuteCount = new AtomicLong();
private final AtomicLong jdbcCommitCount = new AtomicLong();
private final AtomicLong jdbcRollbackCount = new AtomicLong();
private final static ThreadLocal<WebURIStat> currentLocal = new ThreadLocal<WebURIStat>();
public WebURIStat(String uri){
super();
this.uri = uri;
}
public static WebURIStat current() {
return currentLocal.get();
}
public String getUri() {
return uri;
}
public void beforeInvoke(String uri) {
currentLocal.set(this);
int running = runningCount.incrementAndGet();
for (;;) {
int max = concurrentMax.get();
if (running > max) {
if (concurrentMax.compareAndSet(max, running)) {
break;
} else {
continue;
}
} else {
break;
}
}
count.incrementAndGet();
}
public void afterInvoke(long nanoSpan) {
runningCount.decrementAndGet();
currentLocal.set(null);
}
public void addJdbcFetchRowCount(long delta) {
this.jdbcFetchRowCount.addAndGet(delta);
}
public long getJdbcFetchRowCount() {
return jdbcFetchRowCount.get();
}
public long getJdbcFetchRowPeak() {
return jdbcFetchRowPeak.get();
}
public void addJdbcUpdateCount(int updateCount) {
this.jdbcUpdateCount.addAndGet(updateCount);
}
public long getJdbcUpdateCount() {
return jdbcUpdateCount.get();
}
public void incrementJdbcExecuteCount() {
jdbcExecuteCount.incrementAndGet();
}
public long getJdbcExecuteCount() {
return jdbcExecuteCount.get();
}
public void incrementJdbcCommitCount() {
jdbcCommitCount.incrementAndGet();
}
public long getJdbcCommitCount() {
return jdbcCommitCount.get();
}
public void incrementJdbcRollbackCount() {
jdbcRollbackCount.incrementAndGet();
}
public long getJdbcRollbackCount() {
return jdbcRollbackCount.get();
}
}