mirror of
https://github.com/alibaba/druid.git
synced 2023-03-04 19:17:16 +00:00
StatView refactor
This commit is contained in:
@@ -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());
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user