cache the reflect class and reflect method.

This commit is contained in:
septer
2012-08-10 20:46:56 +08:00
5 changed files with 80 additions and 61 deletions
+12 -11
View File
@@ -213,7 +213,7 @@
</dependencies>
</profile>
</profiles>
<dependencies>
<dependency>
<groupId>javax.servlet</groupId>
@@ -252,18 +252,18 @@
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.1.1</version>
<scope>provided</scope>
<optional>true</optional>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.1.1</version>
<scope>provided</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis-spring</artifactId>
<version>1.1.1</version>
<scope>provided</scope>
<optional>true</optional>
<groupId>org.mybatis</groupId>
<artifactId>mybatis-spring</artifactId>
<version>1.1.1</version>
<scope>provided</scope>
<optional>true</optional>
</dependency>
<dependency>
@@ -321,6 +321,7 @@
<version>10.2.0.2</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.microsoft.sqlserver</groupId>
<artifactId>sqljdbc4</artifactId>
@@ -81,6 +81,8 @@ public class StatFilter extends FilterEventAdapter implements StatFilterMBean {
// 3 seconds is slow sql
protected long slowSqlMillis = 3 * 1000;
protected boolean logSlowSql = false;
private String dbType;
private boolean mergeSql = false;
@@ -182,6 +184,15 @@ public class StatFilter extends FilterEventAdapter implements StatFilterMBean {
}
}
}
{
String property = properties.getProperty("druid.stat.logSlowSql");
if ("true".equals(property)) {
this.logSlowSql = true;
} else if ("false".equals(property)) {
this.logSlowSql = false;
}
}
}
@Override
@@ -507,6 +518,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());
}
}
}
}
@@ -16,14 +16,18 @@ import com.alibaba.druid.sql.dialect.sqlserver.visitor.SQLServerOutputVisitor;
import com.alibaba.druid.sql.dialect.sqlserver.visitor.SQLServerSchemaStatVisitor;
import com.alibaba.druid.sql.parser.ParserException;
import com.alibaba.druid.sql.parser.SQLExprParser;
import com.alibaba.druid.sql.parser.SQLParseException;
import com.alibaba.druid.sql.parser.SQLParserUtils;
import com.alibaba.druid.sql.parser.SQLStatementParser;
import com.alibaba.druid.sql.parser.Token;
import com.alibaba.druid.sql.visitor.SQLASTOutputVisitor;
import com.alibaba.druid.sql.visitor.SchemaStatVisitor;
import com.alibaba.druid.support.logging.Log;
import com.alibaba.druid.support.logging.LogFactory;
import com.alibaba.druid.util.JdbcUtils;
public class SQLUtils {
private final static Log LOG = LogFactory.getLog(SQLUtils.class);
public static String toSQLString(SQLObject sqlObject, String dbType) {
if (JdbcUtils.MYSQL.equals(dbType)) {
@@ -118,16 +122,22 @@ public class SQLUtils {
}
public static String format(String sql, String dbType) {
List<SQLStatement> statementList = toStatementList(sql, dbType);
try {
List<SQLStatement> statementList = toStatementList(sql, dbType);
StringBuilder out = new StringBuilder();
SQLASTOutputVisitor visitor = createFormatOutputVisitor(out, statementList, dbType);
StringBuilder out = new StringBuilder();
SQLASTOutputVisitor visitor = createFormatOutputVisitor(out, statementList, dbType);
for (SQLStatement stmt : statementList) {
stmt.accept(visitor);
for (SQLStatement stmt : statementList) {
stmt.accept(visitor);
}
return out.toString();
} catch (SQLParseException ex) {
LOG.warn("format error", ex);
return sql;
}
return out.toString();
}
public static SQLASTOutputVisitor createFormatOutputVisitor(Appendable out, List<SQLStatement> statementList,
@@ -4,23 +4,24 @@ import java.io.IOException;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.List;
import java.util.Map;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import com.alibaba.druid.pool.DruidDataSource;
import com.alibaba.druid.sql.SQLUtils;
import com.alibaba.druid.sql.ast.SQLStatement;
import com.alibaba.druid.sql.visitor.SchemaStatVisitor;
import com.alibaba.druid.stat.DruidStatManagerFacade;
import com.alibaba.druid.stat.JdbcSqlStat;
import com.alibaba.druid.support.JSONDruidStatService;
import com.alibaba.druid.util.IOUtils;
import com.alibaba.druid.util.StringUtils;
/**
* 注意:避免直接调用Druid相关对象例如DruidDataSource等,相关调用要到DruidStatManagerFacade里用反射实现
*
* @author sandzhang<sandzhangtoo@gmail.com>
*/
public class StatViewServlet extends HttpServlet {
@@ -37,7 +38,7 @@ 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 static DateFormat format = new SimpleDateFormat("yyyy/MM/dd hh:mm:ss:SSS");
public void init() throws ServletException {
try {
@@ -76,22 +77,19 @@ public class StatViewServlet extends HttpServlet {
if (path.startsWith("/connectionInfo-") && path.endsWith(".html")) {
Integer id = StringUtils.subStringToInteger(path, "connectionInfo-", ".");
DruidDataSource datasource = druidStatManager.getDruidDataSourceById(id);
returnViewConnectionInfo(datasource, request, response);
returnViewConnectionInfo(id, request, response);
return;
}
if (path.startsWith("/activeConnectionStackTrace-") && path.endsWith(".html")) {
Integer id = StringUtils.subStringToInteger(path, "activeConnectionStackTrace-", ".");
DruidDataSource datasource = druidStatManager.getDruidDataSourceById(id);
returnViewActiveConnectionStackTrace(datasource, request, response);
returnViewActiveConnectionStackTrace(id, request, response);
return;
}
if (path.startsWith("/sql-") && path.endsWith(".html")) {
Integer id = StringUtils.subStringToInteger(path, "sql-", ".");
JdbcSqlStat sqlStat = druidStatManager.getSqlStatById(id);
returnViewSqlStat(sqlStat, response);
returnViewSqlStat(druidStatManager.getSqlStatData(id), response);
return;
}
@@ -99,63 +97,58 @@ public class StatViewServlet extends HttpServlet {
returnResourceFile(path, response);
}
private void returnViewActiveConnectionStackTrace(DruidDataSource datasource, HttpServletRequest request,
private void returnViewActiveConnectionStackTrace(Integer id, HttpServletRequest request,
HttpServletResponse response) throws IOException {
if (datasource == null) return;
if (!datasource.isRemoveAbandoned()) {
response.getWriter().print(mergeTemplatePage("ERROR", "require set removeAbandoned=true"));
return;
}
String text = IOUtils.readFromResource(RESOURCE_PATH + "/activeConnectionStackTrace.html");
text = text.replaceAll("\\{datasourceId\\}", String.valueOf(System.identityHashCode(datasource)));
text = text.replaceAll("\\{datasourceId\\}", id.toString());
response.getWriter().print(text);
}
private void returnViewConnectionInfo(DruidDataSource datasource, HttpServletRequest request,
HttpServletResponse response) throws IOException {
if (datasource == null) return;
private void returnViewConnectionInfo(Integer id, HttpServletRequest request, HttpServletResponse response)
throws IOException {
String text = IOUtils.readFromResource(RESOURCE_PATH + "/connectionInfo.html");
text = text.replaceAll("\\{datasourceId\\}", String.valueOf(System.identityHashCode(datasource)));
text = text.replaceAll("\\{datasourceId\\}", id.toString());
response.getWriter().print(text);
}
private void returnViewSqlStat(JdbcSqlStat sqlStat, HttpServletResponse response) throws IOException {
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.getSql() + "</h4>");
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(sqlStat.getSql(), sqlStat.getDbType()));
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.getLastSlowParameters() != null && sqlStat.getLastSlowParameters().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'>MaxTimespanOccurTime</td>");
content.append("<td>" + format.format(sqlStat.getExecuteNanoSpanMaxOccurTime()) + "</td>");
content.append("</tr>");
content.append("<tr>");
content.append("<td class='td_lable' width='130'>LastSlowParameters</td>");
content.append("<td>" + sqlStat.getLastSlowParameters() + "</td>");
content.append("</tr>");
content.append("</table>");
content.append("<br />");
}
List<SQLStatement> statementList = SQLUtils.parseStatements(sqlStat.getSql(), sqlStat.getDbType());
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, sqlStat.getDbType());
SchemaStatVisitor visitor = SQLUtils.createSchemaStatVisitor(statementList, (String) sqlStat.get("DbType"));
statemen.accept(visitor);
content.append("<table cellpadding='5' cellspacing='1' width='99%'>");
content.append("<tr>");
View File