mirror of
https://github.com/alibaba/druid.git
synced 2023-03-04 19:17:16 +00:00
improve spring-mvc stat support
This commit is contained in:
@@ -0,0 +1,256 @@
|
||||
/*
|
||||
* Copyright 1999-2011 Alibaba Group Holding Ltd.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.alibaba.druid.support.http;
|
||||
|
||||
import javax.servlet.http.Cookie;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpSession;
|
||||
|
||||
import com.alibaba.druid.filter.stat.StatFilterContextListenerAdapter;
|
||||
import com.alibaba.druid.support.http.stat.WebAppStat;
|
||||
import com.alibaba.druid.support.http.stat.WebRequestStat;
|
||||
import com.alibaba.druid.support.http.stat.WebSessionStat;
|
||||
import com.alibaba.druid.util.DruidWebUtils;
|
||||
|
||||
public class AbstractWebStatImpl {
|
||||
|
||||
public final static int DEFAULT_MAX_STAT_SESSION_COUNT = 1000 * 1;
|
||||
|
||||
protected WebAppStat webAppStat = null;
|
||||
|
||||
protected boolean sessionStatEnable = true;
|
||||
protected int sessionStatMaxCount = DEFAULT_MAX_STAT_SESSION_COUNT;
|
||||
protected boolean createSession = false;
|
||||
protected boolean profileEnable = false;
|
||||
|
||||
protected String contextPath;
|
||||
|
||||
protected String principalSessionName;
|
||||
protected String principalCookieName;
|
||||
protected String realIpHeader;
|
||||
|
||||
protected WebStatFilterContextListener statFilterContextListener = new WebStatFilterContextListener();
|
||||
|
||||
public boolean isSessionStatEnable() {
|
||||
return sessionStatEnable;
|
||||
}
|
||||
|
||||
public void setSessionStatEnable(boolean sessionStatEnable) {
|
||||
this.sessionStatEnable = sessionStatEnable;
|
||||
}
|
||||
|
||||
public boolean isProfileEnable() {
|
||||
return profileEnable;
|
||||
}
|
||||
|
||||
public void setProfileEnable(boolean profileEnable) {
|
||||
this.profileEnable = profileEnable;
|
||||
}
|
||||
|
||||
public String getContextPath() {
|
||||
return contextPath;
|
||||
}
|
||||
|
||||
public int getSessionStatMaxCount() {
|
||||
return sessionStatMaxCount;
|
||||
}
|
||||
|
||||
public String getRequestURI(HttpServletRequest request) {
|
||||
return request.getRequestURI();
|
||||
}
|
||||
|
||||
public String getPrincipalSessionName() {
|
||||
return principalSessionName;
|
||||
}
|
||||
|
||||
public String getPrincipalCookieName() {
|
||||
return principalCookieName;
|
||||
}
|
||||
|
||||
public WebSessionStat getSessionStat(HttpServletRequest request) {
|
||||
if (!isSessionStatEnable()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
WebSessionStat sessionStat = null;
|
||||
String sessionId = getSessionId(request);
|
||||
if (sessionId != null) {
|
||||
sessionStat = webAppStat.getSessionStat(sessionId, true);
|
||||
}
|
||||
|
||||
if (sessionStat != null) {
|
||||
long currentMillis = System.currentTimeMillis();
|
||||
|
||||
String userAgent = request.getHeader("user-agent");
|
||||
|
||||
if (sessionStat.getCreateTimeMillis() == -1L) {
|
||||
HttpSession session = request.getSession(false);
|
||||
|
||||
if (session != null) {
|
||||
sessionStat.setCreateTimeMillis(session.getCreationTime());
|
||||
} else {
|
||||
sessionStat.setCreateTimeMillis(currentMillis);
|
||||
}
|
||||
|
||||
webAppStat.computeUserAgent(userAgent);
|
||||
webAppStat.incrementSessionCount();
|
||||
}
|
||||
|
||||
sessionStat.setUserAgent(userAgent);
|
||||
|
||||
String ip = getRemoteAddress(request);
|
||||
|
||||
sessionStat.addRemoteAddress(ip);
|
||||
}
|
||||
|
||||
return sessionStat;
|
||||
}
|
||||
|
||||
protected String getRemoteAddress(HttpServletRequest request) {
|
||||
String ip = null;
|
||||
if (this.realIpHeader != null && this.realIpHeader.length() != 0) {
|
||||
ip = request.getHeader(realIpHeader);
|
||||
}
|
||||
if (ip == null || ip.length() == 0) {
|
||||
ip = DruidWebUtils.getRemoteAddr(request);
|
||||
}
|
||||
return ip;
|
||||
}
|
||||
|
||||
public String getSessionId(HttpServletRequest httpRequest) {
|
||||
String sessionId = null;
|
||||
|
||||
HttpSession session = httpRequest.getSession(createSession);
|
||||
if (session != null) {
|
||||
sessionId = session.getId();
|
||||
}
|
||||
|
||||
return sessionId;
|
||||
}
|
||||
|
||||
public String getPrincipal(HttpServletRequest httpRequest) {
|
||||
if (principalSessionName != null) {
|
||||
HttpSession session = httpRequest.getSession(createSession);
|
||||
if (session == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
Object sessionValue = session.getAttribute(principalSessionName);
|
||||
|
||||
if (sessionValue == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return sessionValue.toString();
|
||||
}
|
||||
|
||||
if (principalCookieName != null && httpRequest.getCookies() != null) {
|
||||
for (Cookie cookie : httpRequest.getCookies()) {
|
||||
if (principalCookieName.equals(cookie.getName())) {
|
||||
return cookie.getValue();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public class WebStatFilterContextListener extends StatFilterContextListenerAdapter {
|
||||
|
||||
@Override
|
||||
public void addUpdateCount(int updateCount) {
|
||||
WebRequestStat reqStat = WebRequestStat.current();
|
||||
if (reqStat != null) {
|
||||
reqStat.addJdbcUpdateCount(updateCount);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addFetchRowCount(int fetchRowCount) {
|
||||
WebRequestStat reqStat = WebRequestStat.current();
|
||||
if (reqStat != null) {
|
||||
reqStat.addJdbcFetchRowCount(fetchRowCount);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void executeBefore(String sql, boolean inTransaction) {
|
||||
WebRequestStat reqStat = WebRequestStat.current();
|
||||
if (reqStat != null) {
|
||||
reqStat.incrementJdbcExecuteCount();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void executeAfter(String sql, long nanos, Throwable error) {
|
||||
WebRequestStat reqStat = WebRequestStat.current();
|
||||
if (reqStat != null) {
|
||||
reqStat.addJdbcExecuteTimeNano(nanos);
|
||||
if (error != null) {
|
||||
reqStat.incrementJdbcExecuteErrorCount();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void commit() {
|
||||
WebRequestStat reqStat = WebRequestStat.current();
|
||||
if (reqStat != null) {
|
||||
reqStat.incrementJdbcCommitCount();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void rollback() {
|
||||
WebRequestStat reqStat = WebRequestStat.current();
|
||||
if (reqStat != null) {
|
||||
reqStat.incrementJdbcRollbackCount();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void pool_connect() {
|
||||
WebRequestStat reqStat = WebRequestStat.current();
|
||||
if (reqStat != null) {
|
||||
reqStat.incrementJdbcPoolConnectCount();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void pool_close(long nanos) {
|
||||
WebRequestStat reqStat = WebRequestStat.current();
|
||||
if (reqStat != null) {
|
||||
reqStat.incrementJdbcPoolCloseCount();
|
||||
}
|
||||
}
|
||||
|
||||
@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();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -27,14 +27,11 @@ import javax.servlet.FilterConfig;
|
||||
import javax.servlet.ServletException;
|
||||
import javax.servlet.ServletRequest;
|
||||
import javax.servlet.ServletResponse;
|
||||
import javax.servlet.http.Cookie;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import javax.servlet.http.HttpServletResponseWrapper;
|
||||
import javax.servlet.http.HttpSession;
|
||||
|
||||
import com.alibaba.druid.filter.stat.StatFilterContext;
|
||||
import com.alibaba.druid.filter.stat.StatFilterContextListenerAdapter;
|
||||
import com.alibaba.druid.support.http.stat.WebAppStat;
|
||||
import com.alibaba.druid.support.http.stat.WebAppStatManager;
|
||||
import com.alibaba.druid.support.http.stat.WebRequestStat;
|
||||
@@ -55,39 +52,24 @@ import com.alibaba.druid.util.ServletPathMatcher;
|
||||
* @author wenshao <szujobs@htomail.com>
|
||||
* @author Zhangming Qi <qizhanming@gmail.com>
|
||||
*/
|
||||
public class WebStatFilter implements Filter {
|
||||
public class WebStatFilter extends AbstractWebStatImpl implements Filter {
|
||||
|
||||
private final static Log LOG = LogFactory.getLog(WebStatFilter.class);
|
||||
private final static Log LOG = LogFactory.getLog(WebStatFilter.class);
|
||||
|
||||
public final static String PARAM_NAME_PORFILE_ENABLE = "profileEnable";
|
||||
public final static String PARAM_NAME_SESSION_STAT_ENABLE = "sessionStatEnable";
|
||||
public final static String PARAM_NAME_SESSION_STAT_MAX_COUNT = "sessionStatMaxCount";
|
||||
public static final String PARAM_NAME_EXCLUSIONS = "exclusions";
|
||||
public static final String PARAM_NAME_PRINCIPAL_SESSION_NAME = "principalSessionName";
|
||||
public static final String PARAM_NAME_PRINCIPAL_COOKIE_NAME = "principalCookieName";
|
||||
public static final String PARAM_NAME_REAL_IP_HEADER = "realIpHeader";
|
||||
public final static String PARAM_NAME_PORFILE_ENABLE = "profileEnable";
|
||||
public final static String PARAM_NAME_SESSION_STAT_ENABLE = "sessionStatEnable";
|
||||
public final static String PARAM_NAME_SESSION_STAT_MAX_COUNT = "sessionStatMaxCount";
|
||||
public static final String PARAM_NAME_EXCLUSIONS = "exclusions";
|
||||
public static final String PARAM_NAME_PRINCIPAL_SESSION_NAME = "principalSessionName";
|
||||
public static final String PARAM_NAME_PRINCIPAL_COOKIE_NAME = "principalCookieName";
|
||||
public static final String PARAM_NAME_REAL_IP_HEADER = "realIpHeader";
|
||||
|
||||
public final static int DEFAULT_MAX_STAT_SESSION_COUNT = 1000 * 100;
|
||||
|
||||
private WebAppStat webAppStat = null;
|
||||
private WebStatFilterContextListener statFilterContextListener = new WebStatFilterContextListener();
|
||||
/**
|
||||
* PatternMatcher used in determining which paths to react to for a given request.
|
||||
*/
|
||||
protected PatternMatcher pathMatcher = new ServletPathMatcher();
|
||||
protected PatternMatcher pathMatcher = new ServletPathMatcher();
|
||||
|
||||
private Set<String> excludesPattern;
|
||||
|
||||
private boolean sessionStatEnable = true;
|
||||
private int sessionStatMaxCount = DEFAULT_MAX_STAT_SESSION_COUNT;
|
||||
private boolean createSession = false;
|
||||
private boolean profileEnable = false;
|
||||
|
||||
private String contextPath;
|
||||
|
||||
private String principalSessionName;
|
||||
private String principalCookieName;
|
||||
private String realIpHeader;
|
||||
private Set<String> excludesPattern;
|
||||
|
||||
@Override
|
||||
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException,
|
||||
@@ -203,94 +185,6 @@ public class WebStatFilter implements Filter {
|
||||
}
|
||||
}
|
||||
|
||||
public WebSessionStat getSessionStat(HttpServletRequest request) {
|
||||
if (!isSessionStatEnable()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
WebSessionStat sessionStat = null;
|
||||
String sessionId = getSessionId(request);
|
||||
if (sessionId != null) {
|
||||
sessionStat = webAppStat.getSessionStat(sessionId, true);
|
||||
}
|
||||
|
||||
if (sessionStat != null) {
|
||||
long currentMillis = System.currentTimeMillis();
|
||||
|
||||
String userAgent = request.getHeader("user-agent");
|
||||
|
||||
if (sessionStat.getCreateTimeMillis() == -1L) {
|
||||
HttpSession session = request.getSession(false);
|
||||
|
||||
if (session != null) {
|
||||
sessionStat.setCreateTimeMillis(session.getCreationTime());
|
||||
} else {
|
||||
sessionStat.setCreateTimeMillis(currentMillis);
|
||||
}
|
||||
|
||||
webAppStat.computeUserAgent(userAgent);
|
||||
webAppStat.incrementSessionCount();
|
||||
}
|
||||
|
||||
sessionStat.setUserAgent(userAgent);
|
||||
|
||||
String ip = getRemoteAddress(request);
|
||||
|
||||
sessionStat.addRemoteAddress(ip);
|
||||
}
|
||||
|
||||
return sessionStat;
|
||||
}
|
||||
|
||||
protected String getRemoteAddress(HttpServletRequest request) {
|
||||
String ip = null;
|
||||
if (this.realIpHeader != null && this.realIpHeader.length() != 0) {
|
||||
ip = request.getHeader(realIpHeader);
|
||||
}
|
||||
if (ip == null || ip.length() == 0) {
|
||||
ip = DruidWebUtils.getRemoteAddr(request);
|
||||
}
|
||||
return ip;
|
||||
}
|
||||
|
||||
public String getSessionId(HttpServletRequest httpRequest) {
|
||||
String sessionId = null;
|
||||
|
||||
HttpSession session = httpRequest.getSession(createSession);
|
||||
if (session != null) {
|
||||
sessionId = session.getId();
|
||||
}
|
||||
|
||||
return sessionId;
|
||||
}
|
||||
|
||||
public String getPrincipal(HttpServletRequest httpRequest) {
|
||||
if (principalSessionName != null) {
|
||||
HttpSession session = httpRequest.getSession(createSession);
|
||||
if (session == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
Object sessionValue = session.getAttribute(principalSessionName);
|
||||
|
||||
if (sessionValue == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return sessionValue.toString();
|
||||
}
|
||||
|
||||
if (principalCookieName != null && httpRequest.getCookies() != null) {
|
||||
for (Cookie cookie : httpRequest.getCookies()) {
|
||||
if (principalCookieName.equals(cookie.getName())) {
|
||||
return cookie.getValue();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public boolean isExclusion(String requestURI) {
|
||||
if (excludesPattern == null) {
|
||||
return false;
|
||||
@@ -312,18 +206,6 @@ public class WebStatFilter implements Filter {
|
||||
return false;
|
||||
}
|
||||
|
||||
public String getRequestURI(HttpServletRequest request) {
|
||||
return request.getRequestURI();
|
||||
}
|
||||
|
||||
public String getPrincipalSessionName() {
|
||||
return principalSessionName;
|
||||
}
|
||||
|
||||
public String getPrincipalCookieName() {
|
||||
return principalCookieName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void init(FilterConfig config) throws ServletException {
|
||||
{
|
||||
@@ -421,22 +303,6 @@ public class WebStatFilter implements Filter {
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isSessionStatEnable() {
|
||||
return sessionStatEnable;
|
||||
}
|
||||
|
||||
public void setSessionStatEnable(boolean sessionStatEnable) {
|
||||
this.sessionStatEnable = sessionStatEnable;
|
||||
}
|
||||
|
||||
public boolean isProfileEnable() {
|
||||
return profileEnable;
|
||||
}
|
||||
|
||||
public void setProfileEnable(boolean profileEnable) {
|
||||
this.profileEnable = profileEnable;
|
||||
}
|
||||
|
||||
public void setWebAppStat(WebAppStat webAppStat) {
|
||||
this.webAppStat = webAppStat;
|
||||
}
|
||||
@@ -445,104 +311,10 @@ public class WebStatFilter implements Filter {
|
||||
return webAppStat;
|
||||
}
|
||||
|
||||
public String getContextPath() {
|
||||
return contextPath;
|
||||
}
|
||||
|
||||
public int getSessionStatMaxCount() {
|
||||
return sessionStatMaxCount;
|
||||
}
|
||||
|
||||
public WebStatFilterContextListener getStatFilterContextListener() {
|
||||
return statFilterContextListener;
|
||||
}
|
||||
|
||||
class WebStatFilterContextListener extends StatFilterContextListenerAdapter {
|
||||
|
||||
@Override
|
||||
public void addUpdateCount(int updateCount) {
|
||||
WebRequestStat reqStat = WebRequestStat.current();
|
||||
if (reqStat != null) {
|
||||
reqStat.addJdbcUpdateCount(updateCount);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addFetchRowCount(int fetchRowCount) {
|
||||
WebRequestStat reqStat = WebRequestStat.current();
|
||||
if (reqStat != null) {
|
||||
reqStat.addJdbcFetchRowCount(fetchRowCount);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void executeBefore(String sql, boolean inTransaction) {
|
||||
WebRequestStat reqStat = WebRequestStat.current();
|
||||
if (reqStat != null) {
|
||||
reqStat.incrementJdbcExecuteCount();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void executeAfter(String sql, long nanos, Throwable error) {
|
||||
WebRequestStat reqStat = WebRequestStat.current();
|
||||
if (reqStat != null) {
|
||||
reqStat.addJdbcExecuteTimeNano(nanos);
|
||||
if (error != null) {
|
||||
reqStat.incrementJdbcExecuteErrorCount();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void commit() {
|
||||
WebRequestStat reqStat = WebRequestStat.current();
|
||||
if (reqStat != null) {
|
||||
reqStat.incrementJdbcCommitCount();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void rollback() {
|
||||
WebRequestStat reqStat = WebRequestStat.current();
|
||||
if (reqStat != null) {
|
||||
reqStat.incrementJdbcRollbackCount();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void pool_connect() {
|
||||
WebRequestStat reqStat = WebRequestStat.current();
|
||||
if (reqStat != null) {
|
||||
reqStat.incrementJdbcPoolConnectCount();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void pool_close(long nanos) {
|
||||
WebRequestStat reqStat = WebRequestStat.current();
|
||||
if (reqStat != null) {
|
||||
reqStat.incrementJdbcPoolCloseCount();
|
||||
}
|
||||
}
|
||||
|
||||
@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 {
|
||||
|
||||
private int status;
|
||||
|
||||
@@ -23,6 +23,7 @@ import java.util.Set;
|
||||
import java.util.concurrent.CopyOnWriteArraySet;
|
||||
|
||||
import com.alibaba.druid.stat.DruidDataSourceStatManager;
|
||||
import com.alibaba.druid.util.StringUtils;
|
||||
|
||||
public class WebAppStatManager {
|
||||
|
||||
@@ -35,6 +36,22 @@ public class WebAppStatManager {
|
||||
public static WebAppStatManager getInstance() {
|
||||
return instance;
|
||||
}
|
||||
|
||||
public synchronized WebAppStat getWebAppStat(String contextPath) {
|
||||
Set<Object> stats = getWebAppStatSet();
|
||||
for (Object item : stats) {
|
||||
if (item instanceof WebAppStat) {
|
||||
WebAppStat stat = (WebAppStat) item;
|
||||
if (StringUtils.equals(stat.getContextPath(), contextPath)) {
|
||||
return stat;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
WebAppStat stat = new WebAppStat(contextPath);
|
||||
this.addWebAppStatSet(stat);
|
||||
return stat;
|
||||
}
|
||||
|
||||
public Set<Object> getWebAppStatSet() {
|
||||
if (webAppStatSet == null) {
|
||||
|
||||
@@ -0,0 +1,162 @@
|
||||
/*
|
||||
* Copyright 1999-2011 Alibaba Group Holding Ltd.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.alibaba.druid.support.spring.mvc;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import javax.servlet.ServletContext;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import org.springframework.beans.factory.DisposableBean;
|
||||
import org.springframework.beans.factory.InitializingBean;
|
||||
import org.springframework.web.servlet.HandlerInterceptor;
|
||||
import org.springframework.web.servlet.HandlerMapping;
|
||||
import org.springframework.web.servlet.ModelAndView;
|
||||
|
||||
import com.alibaba.druid.filter.stat.StatFilterContext;
|
||||
import com.alibaba.druid.support.http.AbstractWebStatImpl;
|
||||
import com.alibaba.druid.support.http.stat.WebAppStat;
|
||||
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.profile.ProfileEntryKey;
|
||||
import com.alibaba.druid.support.profile.ProfileEntryReqStat;
|
||||
import com.alibaba.druid.support.profile.Profiler;
|
||||
import com.alibaba.druid.util.DruidWebUtils;
|
||||
|
||||
public class StatHandlerInterceptor extends AbstractWebStatImpl implements HandlerInterceptor, InitializingBean, DisposableBean {
|
||||
|
||||
public StatHandlerInterceptor(){
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
|
||||
final WebAppStat webAppStat = getWebAppStat(request);
|
||||
String requestURI = getRequestURI(request);
|
||||
|
||||
long startNano = System.nanoTime();
|
||||
long startMillis = System.currentTimeMillis();
|
||||
|
||||
WebRequestStat requestStat = new WebRequestStat(startNano, startMillis);
|
||||
WebRequestStat.set(requestStat);
|
||||
|
||||
WebSessionStat sessionStat = getSessionStat(request);
|
||||
webAppStat.beforeInvoke();
|
||||
|
||||
WebURIStat uriStat = webAppStat.getURIStat(requestURI, false);
|
||||
|
||||
if (uriStat == null) {
|
||||
int index = requestURI.indexOf(";jsessionid=");
|
||||
if (index != -1) {
|
||||
requestURI = requestURI.substring(0, index);
|
||||
uriStat = webAppStat.getURIStat(requestURI, false);
|
||||
}
|
||||
}
|
||||
|
||||
if (isProfileEnable()) {
|
||||
Profiler.initLocal();
|
||||
Profiler.enter(requestURI, Profiler.PROFILE_TYPE_WEB);
|
||||
}
|
||||
|
||||
// 第一次访问时,uriStat这里为null,是为了防止404攻击。
|
||||
if (uriStat != null) {
|
||||
uriStat.beforeInvoke();
|
||||
}
|
||||
|
||||
// 第一次访问时,sessionId为null,如果缺省sessionCreate=false,sessionStat就为null。
|
||||
if (sessionStat != null) {
|
||||
sessionStat.beforeInvoke();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public WebAppStat getWebAppStat(HttpServletRequest request) {
|
||||
if (webAppStat != null) {
|
||||
return webAppStat;
|
||||
}
|
||||
|
||||
ServletContext context = request.getSession().getServletContext();
|
||||
String contextPath = DruidWebUtils.getContextPath(context);
|
||||
webAppStat = WebAppStatManager.getInstance().getWebAppStat(contextPath);
|
||||
return webAppStat;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
|
||||
ModelAndView modelAndView) throws Exception {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler,
|
||||
Exception error) throws Exception {
|
||||
WebRequestStat requestStat = WebRequestStat.current();
|
||||
long endNano = System.nanoTime();
|
||||
requestStat.setEndNano(endNano);
|
||||
|
||||
WebSessionStat sessionStat = getSessionStat(request);
|
||||
WebURIStat uriStat = WebURIStat.current();
|
||||
|
||||
long nanos = endNano - requestStat.getStartNano();
|
||||
webAppStat.afterInvoke(null, nanos);
|
||||
|
||||
if (sessionStat == null) {
|
||||
sessionStat = getSessionStat(request);
|
||||
if (sessionStat != null) {
|
||||
sessionStat.beforeInvoke(); // 补偿
|
||||
}
|
||||
}
|
||||
|
||||
if (sessionStat != null) {
|
||||
sessionStat.afterInvoke(error, nanos);
|
||||
sessionStat.setPrincipal(getPrincipal(request));
|
||||
}
|
||||
|
||||
if (uriStat != null) {
|
||||
uriStat.afterInvoke(error, nanos);
|
||||
}
|
||||
|
||||
WebRequestStat.set(null);
|
||||
|
||||
if (isProfileEnable()) {
|
||||
Profiler.release(nanos);
|
||||
|
||||
Map<ProfileEntryKey, ProfileEntryReqStat> requestStatsMap = Profiler.getStatsMap();
|
||||
if (uriStat != null) {
|
||||
uriStat.getProfiletat().record(requestStatsMap);
|
||||
}
|
||||
Profiler.removeLocal();
|
||||
}
|
||||
}
|
||||
|
||||
public String getRequestURI(HttpServletRequest request) {
|
||||
return (String) request.getAttribute(HandlerMapping.PATH_WITHIN_HANDLER_MAPPING_ATTRIBUTE);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void afterPropertiesSet() throws Exception {
|
||||
StatFilterContext.getInstance().addContextListener(statFilterContextListener);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void destroy() throws Exception {
|
||||
StatFilterContext.getInstance().removeContextListener(statFilterContextListener);
|
||||
}
|
||||
}
|
||||
@@ -34,7 +34,7 @@ public class DruidWebUtils {
|
||||
|
||||
return ip;
|
||||
}
|
||||
|
||||
|
||||
private static String getContextPath_2_5(ServletContext context) {
|
||||
String contextPath = context.getContextPath();
|
||||
|
||||
@@ -56,4 +56,5 @@ public class DruidWebUtils {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user