mirror of
https://github.com/alibaba/druid.git
synced 2023-03-04 19:17:16 +00:00
cache the reflect class and reflect method.
This commit is contained in:
@@ -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>");
|
||||
|
||||
Reference in New Issue
Block a user