Merge pull request #17 from shrekwang/master

改了两点: StatViewServlet加IP过滤, 和sql-{id}.html重构
This commit is contained in:
温高铁
2012-08-15 01:35:39 -07:00
8 changed files with 252 additions and 88 deletions
@@ -135,7 +135,9 @@ public class SQLUtils {
return out.toString();
} catch (SQLParseException ex) {
LOG.warn("format error", ex);
return sql;
} catch (ParserException ex) {
LOG.warn("format error", ex);
return sql;
}
}
@@ -1,5 +1,11 @@
package com.alibaba.druid.support;
import com.alibaba.druid.sql.ast.SQLStatement;
import com.alibaba.druid.sql.visitor.SchemaStatVisitor;
import com.alibaba.druid.sql.SQLUtils;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Collections;
import java.util.LinkedHashMap;
import java.util.List;
@@ -82,9 +88,7 @@ public class JSONDruidStatService {
if (url.startsWith("/sql-") && url.indexOf(".json") > 0) {
Integer id = StringUtils.subStringToInteger(url, "sql-", ".json");
Object result = druidStatManager.getSqlStatData(id);
return returnJSONResult(result == null ? RESULT_CODE_ERROR : RESULT_CODE_SUCCESS, result);
return returnJSONSqlInfo(id);
}
if (url.startsWith("/weburi.json")) {
@@ -162,6 +166,28 @@ public class JSONDruidStatService {
return comparatorOrderBy(array, parameters);
}
private String returnJSONSqlInfo(Integer id) {
Map<String,Object> map = druidStatManager.getSqlStatData(id);
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"));
statemen.accept(visitor);
map.put("parsedTable", visitor.getTables().toString());
map.put("parsedFields", visitor.getColumns().toString());
map.put("parsedConditions", visitor.getConditions().toString());
map.put("parsedRelationships", visitor.getRelationships().toString());
map.put("parsedOrderbycolumns", visitor.getOrderByColumns().toString());
}
DateFormat format = new SimpleDateFormat("yyyy/MM/dd hh:mm:ss:SSS");
map.put("MaxTimespanOccurTime", format.format(map.get("MaxTimespanOccurTime")));
return returnJSONResult(map == null ? RESULT_CODE_ERROR : RESULT_CODE_SUCCESS, map);
}
private String returnJSONActiveConnectionStackTrace(Integer id) {
List<String> result = druidStatManager.getActiveConnectionStackTraceByDataSourceId(id);
@@ -1,5 +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.text.DateFormat;
import java.text.SimpleDateFormat;
@@ -38,14 +41,32 @@ public class StatViewServlet extends HttpServlet {
private static JSONDruidStatService jsonDruidStatService = JSONDruidStatService.getInstance();
public String templatePage;
private static DateFormat format = new SimpleDateFormat("yyyy/MM/dd hh:mm:ss:SSS");
private String permittedIp;
private Pattern ipCheckPattern;
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);
}
}
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;
}
String remoteIp = request.getRemoteAddr();
Matcher matcher = ipCheckPattern.matcher(remoteIp);
return matcher.matches();
}
public void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
@@ -55,11 +76,19 @@ public class StatViewServlet extends HttpServlet {
response.setCharacterEncoding("utf-8");
if (contextPath == null) { // root context
contextPath = "";
}
String uri = contextPath + servletPath;
String path = requestURI.substring(contextPath.length() + servletPath.length());
if (!isPermittedRequest(request)) {
path = "/nopermit.html";
returnResourceFile(path, uri, response);
return;
}
if ("".equals(path)) {
if (contextPath == null || contextPath.equals("") || contextPath.equals("/")) {
@@ -98,7 +127,7 @@ public class StatViewServlet extends HttpServlet {
if (path.startsWith("/sql-") && path.endsWith(".html")) {
Integer id = StringUtils.subStringToInteger(path, "sql-", ".");
returnViewSqlStat(druidStatManager.getSqlStatData(id), response);
returnViewSqlStat(id, request,response);
return;
}
@@ -121,87 +150,14 @@ public class StatViewServlet extends HttpServlet {
response.getWriter().print(text);
}
private void returnViewSqlStat(Map<String, Object> sqlStat, HttpServletResponse response) throws IOException {
if (sqlStat == null) return;
StringBuilder content = new StringBuilder();
content.append("<h2>FULL SQL</h2> <h4>" + sqlStat.get("SQL") + "</h4>");
content.append("<h2>Format View:</h2>");
content.append("<textarea style='width:99%;height:120px;;border:1px #A8C7CE solid;line-height:20px;font-size:12px;'>");
content.append(SQLUtils.format((String) sqlStat.get("SQL"), (String) sqlStat.get("DbType")));
content.append("</textarea><br />");
content.append("<p>API:com.alibaba.druid.sql.SQLUtils.format(sql,DBType);</p>");
content.append("<br />");
if (sqlStat.get("LastSlowParameters") != null
&& sqlStat.get("LastSlowParameters").toString().trim().length() > 0) {
content.append("<h2>LastSlow SQL View:</h2>");
content.append("<table cellpadding='5' cellspacing='1' width='99%'>");
content.append("<tr>");
content.append("<td class='td_lable' width='130'>SlowestSqlOccurTime</td>");
content.append("<td>" + format.format(sqlStat.get("MaxTimespanOccurTime")) + "</td>");
content.append("</tr>");
content.append("<tr>");
content.append("<td class='td_lable' width='130'>LastSlowParameters</td>");
content.append("<td>" + sqlStat.get("LastSlowParameters") + "</td>");
content.append("</tr>");
content.append("</table>");
content.append("<br />");
}
List<SQLStatement> statementList = SQLUtils.parseStatements((String) sqlStat.get("SQL"),
(String) sqlStat.get("DbType"));
if (!statementList.isEmpty()) {
content.append("<h2>Parse View:</h2>");
SQLStatement statemen = statementList.get(0);
SchemaStatVisitor visitor = SQLUtils.createSchemaStatVisitor(statementList, (String) sqlStat.get("DbType"));
statemen.accept(visitor);
content.append("<table cellpadding='5' cellspacing='1' width='99%'>");
content.append("<tr>");
content.append("<td class='td_lable' width='130'>Tables</td>");
content.append("<td>" + visitor.getTables() + "</td>");
content.append("</tr>");
content.append("<tr>");
content.append("<td class='td_lable'>Fields</td>");
content.append("<td>" + visitor.getColumns() + "</td>");
content.append("</tr>");
content.append("<tr>");
content.append("<td class='td_lable'>Coditions</td>");
content.append("<td>" + visitor.getConditions() + "</td>");
content.append("</tr>");
content.append("<tr>");
content.append("<td class='td_lable'>Relationships</td>");
content.append("<td>" + visitor.getRelationships() + "</td>");
content.append("</tr>");
content.append("<tr>");
content.append("<td class='td_lable'>OrderByColumns</td>");
content.append("<td>" + visitor.getOrderByColumns() + "</td>");
content.append("</tr>");
content.append("</table>");
content.append("<br />");
content.append("<p>API:</p>");
content.append("<p>");
content.append("List<SQLStatement> statementList = SQLUtils.parseStatements(sqlStat.getSql(), sqlStat.getDbType())<br />");
content.append("SQLStatement statemen = statementList.get(0);</br>");
content.append("SchemaStatVisitor visitor = SQLUtils.createSchemaStatVisitor(statementList, sqlStat.getDbType());<br />");
content.append("statemen.accept(visitor);<br />");
content.append("visitor.getTables() / visitor.getColumns() / visitor.getOrderByColumns() / visitor.getConditions() / visitor.getRelationships()<br />");
content.append("</p>");
content.append("<br />");
}
response.getWriter().print(mergeTemplatePage("Druid Sql View", content.toString()));
private void returnViewSqlStat(Integer id, HttpServletRequest request, HttpServletResponse response) throws IOException {
String text = IOUtils.readFromResource(RESOURCE_PATH + "/sqlDetail.html");
text = text.replaceAll("\\{sqlId\\}", id.toString());
response.getWriter().print(text);
}
private void returnResourceFile(String fileName, String uri, HttpServletResponse response) throws ServletException, IOException {
String text = IOUtils.readFromResource(RESOURCE_PATH + fileName);
if(text == null) {
@@ -216,7 +172,4 @@ public class StatViewServlet extends HttpServlet {
response.getWriter().write(text);
}
private String mergeTemplatePage(String title, String content) {
return templatePage.replaceAll("\\{title\\}", title).replaceAll("\\{content\\}", content);
}
}
@@ -0,0 +1,18 @@
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());
}
}