StatView refactor

This commit is contained in:
wenshao
2012-08-18 08:45:54 +08:00
parent 7de6700e85
commit 8027c95be9
8 changed files with 248 additions and 129 deletions
@@ -8,6 +8,7 @@ import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.atomic.AtomicLong;
import com.alibaba.druid.VERSION;
import com.alibaba.druid.util.DruidDataSourceUtils;
@@ -25,7 +26,9 @@ import com.alibaba.druid.util.JdbcSqlStatUtils;
*/
public class DruidStatManagerFacade {
private final static DruidStatManagerFacade instance = new DruidStatManagerFacade();
private final static DruidStatManagerFacade instance = new DruidStatManagerFacade();
private boolean resetEnable = true;
private final AtomicLong resetCount = new AtomicLong();
private DruidStatManagerFacade(){
}
@@ -49,6 +52,15 @@ public class DruidStatManagerFacade {
public void resetAll() {
resetSqlStat();
resetDataSourceStat();
resetCount.incrementAndGet();
}
public boolean isResetEnable() {
return resetEnable;
}
public void setResetEnable(boolean resetEnable) {
this.resetEnable = resetEnable;
}
public Object getSqlStatById(Integer id) {
@@ -129,9 +141,15 @@ public class DruidStatManagerFacade {
Map<String, Object> dataMap = new LinkedHashMap<String, Object>();
dataMap.put("Version", VERSION.getVersionNumber());
dataMap.put("Drivers", getDriversData());
dataMap.put("ResetEnable", isResetEnable());
dataMap.put("ResetCount", getResetCount());
return dataMap;
}
public long getResetCount() {
return resetCount.get();
}
private List<String> getDriversData() {
List<String> drivers = new ArrayList<String>();
for (Enumeration<Driver> e = DriverManager.getDrivers(); e.hasMoreElements();) {
@@ -27,7 +27,7 @@ public class JSONDruidStatService {
private final static JSONDruidStatService instance = new JSONDruidStatService();
private static DruidStatManagerFacade druidStatManager = DruidStatManagerFacade.getInstance();
private static DruidStatManagerFacade statManagerFacade = DruidStatManagerFacade.getInstance();
public final static int RESULT_CODE_SUCCESS = 1;
public final static int RESULT_CODE_ERROR = -1;
@@ -44,35 +44,43 @@ public class JSONDruidStatService {
return instance;
}
public boolean isResetEnable() {
return statManagerFacade.isResetEnable();
}
public void setResetEnable(boolean value) {
statManagerFacade.setResetEnable(value);
}
public String service(String url) {
Map<String, String> parameters = StringUtils.getParameters(url);
if (url.equals("/basic.json")) {
return returnJSONResult(RESULT_CODE_SUCCESS, druidStatManager.returnJSONBasicStat());
return returnJSONResult(RESULT_CODE_SUCCESS, statManagerFacade.returnJSONBasicStat());
}
if (url.equals("/reset-all.json")) {
druidStatManager.resetAll();
statManagerFacade.resetAll();
SpringStatManager.getInstance().resetStat();
WebAppStatManager.getInstance().resetStat();
return returnJSONResult(RESULT_CODE_SUCCESS, null);
}
if (url.equals("/datasource.json")) {
return returnJSONResult(RESULT_CODE_SUCCESS, druidStatManager.getDataSourceStatList());
return returnJSONResult(RESULT_CODE_SUCCESS, statManagerFacade.getDataSourceStatList());
}
if (url.startsWith("/datasource-")) {
Integer id = StringUtils.subStringToInteger(url, "datasource-", ".");
Object result = druidStatManager.getDataSourceStatData(id);
Object result = statManagerFacade.getDataSourceStatData(id);
return returnJSONResult(result == null ? RESULT_CODE_ERROR : RESULT_CODE_SUCCESS, result);
}
if (url.startsWith("/connectionInfo-") && url.endsWith(".json")) {
Integer id = StringUtils.subStringToInteger(url, "connectionInfo-", ".");
List<?> connectionInfoList = druidStatManager.getPoolingConnectionInfoByDataSourceId(id);
List<?> connectionInfoList = statManagerFacade.getPoolingConnectionInfoByDataSourceId(id);
return returnJSONResult(connectionInfoList == null ? RESULT_CODE_ERROR : RESULT_CODE_SUCCESS,
connectionInfoList);
}
@@ -90,38 +98,38 @@ public class JSONDruidStatService {
Integer id = StringUtils.subStringToInteger(url, "sql-", ".json");
return returnJSONSqlInfo(id);
}
if (url.startsWith("/weburi.json")) {
return returnJSONResult(RESULT_CODE_SUCCESS, getWebURIStatDataList(parameters));
}
if (url.startsWith("/websession.json")) {
return returnJSONResult(RESULT_CODE_SUCCESS, getWebSessionStatDataList(parameters));
}
if (url.startsWith("/spring.json")) {
return returnJSONResult(RESULT_CODE_SUCCESS, getSpringStatDataList(parameters));
}
return returnJSONResult(RESULT_CODE_ERROR, "Do not support this request, please contact with administrator.");
}
private List<Map<String, Object>> getSpringStatDataList(Map<String, String> parameters) {
List<Map<String, Object>> array = SpringStatManager.getInstance().getMethodStatData();
return comparatorOrderBy(array, parameters);
return comparatorOrderBy(array, parameters);
}
private List<Map<String, Object>> getWebURIStatDataList(Map<String, String> parameters) {
List<Map<String, Object>> array = WebAppStatManager.getInstance().getURIStatData();
return comparatorOrderBy(array, parameters);
return comparatorOrderBy(array, parameters);
}
private List<Map<String, Object>> getWebSessionStatDataList(Map<String, String> parameters) {
List<Map<String, Object>> array = WebAppStatManager.getInstance().getSessionStatData();
return array;
}
private List<Map<String,Object>> comparatorOrderBy(List<Map<String, Object>> array,Map<String, String> parameters){
private List<Map<String, Object>> comparatorOrderBy(List<Map<String, Object>> array, Map<String, String> parameters) {
// when open the stat page before executing some sql
if (array == null || array.isEmpty()) return null;
@@ -160,20 +168,20 @@ public class JSONDruidStatService {
return array.subList(fromIndex, toIndex);
}
private List<Map<String, Object>> getSqlStatDataList(Map<String, String> parameters) {
List<Map<String, Object>> array = druidStatManager.getSqlStatDataList();
List<Map<String, Object>> array = statManagerFacade.getSqlStatDataList();
return comparatorOrderBy(array, parameters);
}
private String returnJSONSqlInfo(Integer id) {
Map<String,Object> map = druidStatManager.getSqlStatData(id);
Map<String, Object> map = statManagerFacade.getSqlStatData(id);
if (map == null) {
return returnJSONResult(RESULT_CODE_ERROR , null);
return returnJSONResult(RESULT_CODE_ERROR, null);
}
map.put("formattedSql",SQLUtils.format((String) map.get("SQL"),(String) map.get("DbType")));
map.put("formattedSql", SQLUtils.format((String) map.get("SQL"), (String) map.get("DbType")));
List<SQLStatement> statementList = SQLUtils.parseStatements((String) map.get("SQL"), (String) map.get("DbType"));
if (!statementList.isEmpty()) {
SQLStatement statemen = statementList.get(0);
SchemaStatVisitor visitor = SQLUtils.createSchemaStatVisitor(statementList, (String) map.get("DbType"));
@@ -184,17 +192,17 @@ public class JSONDruidStatService {
map.put("parsedRelationships", visitor.getRelationships().toString());
map.put("parsedOrderbycolumns", visitor.getOrderByColumns().toString());
}
DateFormat format = new SimpleDateFormat("yyyy/MM/dd hh:mm:ss:SSS");
Date maxTimespanOccurTime = (Date)map.get("MaxTimespanOccurTime");
if (maxTimespanOccurTime != null) {
map.put("MaxTimespanOccurTime", format.format(maxTimespanOccurTime));
}
DateFormat format = new SimpleDateFormat("yyyy/MM/dd hh:mm:ss:SSS");
Date maxTimespanOccurTime = (Date) map.get("MaxTimespanOccurTime");
if (maxTimespanOccurTime != null) {
map.put("MaxTimespanOccurTime", format.format(maxTimespanOccurTime));
}
return returnJSONResult(map == null ? RESULT_CODE_ERROR : RESULT_CODE_SUCCESS, map);
}
private String returnJSONActiveConnectionStackTrace(Integer id) {
List<String> result = druidStatManager.getActiveConnectionStackTraceByDataSourceId(id);
List<String> result = statManagerFacade.getActiveConnectionStackTraceByDataSourceId(id);
if (result == null) {
return returnJSONResult(RESULT_CODE_ERROR, "require set removeAbandoned=true");
@@ -1,9 +1,8 @@
package com.alibaba.druid.support.http;
import com.alibaba.druid.util.IpUtils;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
@@ -11,6 +10,10 @@ import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import com.alibaba.druid.support.JSONDruidStatService;
import com.alibaba.druid.support.http.util.IPAddress;
import com.alibaba.druid.support.http.util.IPRange;
import com.alibaba.druid.support.logging.Log;
import com.alibaba.druid.support.logging.LogFactory;
import com.alibaba.druid.util.IOUtils;
/**
@@ -20,43 +23,110 @@ import com.alibaba.druid.util.IOUtils;
*/
public class StatViewServlet extends HttpServlet {
/**
*
*/
private static final long serialVersionUID = 1L;
private final static Log LOG = LogFactory.getLog(StatViewServlet.class);
private final static String RESOURCE_PATH = "support/http/resources";
private final static String TEMPLATE_PAGE_RESOURCE_PATH = RESOURCE_PATH + "/template.html";
private static final long serialVersionUID = 1L;
private static JSONDruidStatService jsonDruidStatService = JSONDruidStatService.getInstance();
public static final String PARAM_NAME_RESET_ENABLE = "resetEnable";
public static final String PARAM_NAME_ALLOW = "allow";
public static final String PARAM_NAME_DENY = "deny";
public String templatePage;
private final static String RESOURCE_PATH = "support/http/resources";
private final static String TEMPLATE_PAGE_RESOURCE_PATH = RESOURCE_PATH + "/template.html";
private String permittedIp;
private Pattern ipCheckPattern;
private JSONDruidStatService statService = JSONDruidStatService.getInstance();
public String templatePage;
private List<IPRange> allowList = new ArrayList<IPRange>();
private List<IPRange> denyList = new ArrayList<IPRange>();
public void init() throws ServletException {
try {
templatePage = IOUtils.readFromResource(TEMPLATE_PAGE_RESOURCE_PATH);
} catch (IOException e) {
throw new ServletException("error read templatePage:" + TEMPLATE_PAGE_RESOURCE_PATH, e);
}
permittedIp = getServletConfig().getInitParameter("permittedIp");
if (permittedIp != null ) {
this.ipCheckPattern = IpUtils.buildIpCheckPattern(permittedIp);
try {
String param = getInitParameter(PARAM_NAME_RESET_ENABLE);
if (param != null && param.trim().length() != 0) {
param = param.trim();
boolean resetEnable = Boolean.parseBoolean(param);
statService.setResetEnable(resetEnable);
}
} catch (Exception e) {
String msg = "initParameter config error, resetEnable : " + getInitParameter(PARAM_NAME_RESET_ENABLE);
LOG.error(msg, e);
}
try {
String param = getInitParameter(PARAM_NAME_ALLOW);
if (param != null && param.trim().length() != 0) {
param = param.trim();
String[] items = param.split(",");
for (String item : items) {
if (item == null || item.length() == 0) {
continue;
}
IPRange ipRange = new IPRange(item);
allowList.add(ipRange);
}
}
} catch (Exception e) {
String msg = "initParameter config error, allow : " + getInitParameter(PARAM_NAME_ALLOW);
LOG.error(msg, e);
}
try {
String param = getInitParameter(PARAM_NAME_DENY);
if (param != null && param.trim().length() != 0) {
param = param.trim();
String[] items = param.split(",");
for (String item : items) {
if (item == null || item.length() == 0) {
continue;
}
IPRange ipRange = new IPRange(item);
denyList.add(ipRange);
}
}
} catch (Exception e) {
String msg = "initParameter config error, deny : " + getInitParameter(PARAM_NAME_DENY);
LOG.error(msg, e);
}
}
private boolean isPermittedRequest(HttpServletRequest request) {
//if nothing is configured, every host can access the stat result(default)
if (permittedIp == null || permittedIp.trim().equals("")) {
return true;
public boolean isPermittedRequest(HttpServletRequest request) {
String remoteAddress = request.getRemoteAddr();
return isPermittedRequest(remoteAddress);
}
public boolean isPermittedRequest(String remoteAddress) {
IPAddress ipAddress = new IPAddress(remoteAddress);
for (IPRange range : denyList) {
if (range.isIPAddressInRange(ipAddress)) {
return false;
}
}
String remoteIp = request.getRemoteAddr();
Matcher matcher = ipCheckPattern.matcher(remoteIp);
return matcher.matches();
if (allowList.size() > 0) {
for (IPRange range : allowList) {
if (range.isIPAddressInRange(ipAddress)) {
return true;
}
}
return false;
}
return true;
}
public void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
@@ -66,8 +136,6 @@ public class StatViewServlet extends HttpServlet {
response.setCharacterEncoding("utf-8");
if (contextPath == null) { // root context
contextPath = "";
}
@@ -79,7 +147,7 @@ public class StatViewServlet extends HttpServlet {
returnResourceFile(path, uri, response);
return;
}
if ("".equals(path)) {
if (contextPath == null || contextPath.equals("") || contextPath.equals("/")) {
response.sendRedirect("/druid/index.html");
@@ -99,18 +167,18 @@ public class StatViewServlet extends HttpServlet {
if (request.getQueryString() != null && request.getQueryString().length() > 0) {
fullUrl += "?" + request.getQueryString();
}
response.getWriter().print(jsonDruidStatService.service(fullUrl));
response.getWriter().print(statService.service(fullUrl));
return;
}
// find file in resources path
returnResourceFile(path, uri, response);
}
private void returnResourceFile(String fileName, String uri, HttpServletResponse response) throws ServletException, IOException {
private void returnResourceFile(String fileName, String uri, HttpServletResponse response) throws ServletException,
IOException {
String text = IOUtils.readFromResource(RESOURCE_PATH + fileName);
if(text == null) {
if (text == null) {
response.sendRedirect(uri + "/index.html");
return;
}
@@ -1,18 +0,0 @@
package com.alibaba.druid.util;
import java.util.regex.Pattern;
public class IpUtils {
public static Pattern buildIpCheckPattern(String permittedIP) {
String[] addrs = permittedIP.split(",");
StringBuilder sb = new StringBuilder();
for (String addr : addrs ) {
addr = addr.trim();
addr = addr.replace("*", "\\d{1,3}");
sb.append(addr.trim()).append("|");
}
return Pattern.compile(sb.toString());
}
}