mirror of
https://github.com/alibaba/druid.git
synced 2023-03-04 19:17:16 +00:00
Merge remote-tracking branch 'zhb/master'
Conflicts: src/main/java/com/alibaba/druid/support/http/StatViewServlet.java
This commit is contained in:
@@ -96,6 +96,10 @@ public class StatFilter extends FilterEventAdapter implements StatFilterMBean {
|
||||
this.dbType = dbType;
|
||||
}
|
||||
|
||||
public long getSlowSqlMillis() {
|
||||
return slowSqlMillis;
|
||||
}
|
||||
|
||||
public boolean isConnectionStackTraceEnable() {
|
||||
return connectionStackTraceEnable;
|
||||
}
|
||||
@@ -406,7 +410,8 @@ public class StatFilter extends FilterEventAdapter implements StatFilterMBean {
|
||||
}
|
||||
}
|
||||
|
||||
private final void internalAfterStatementExecute(StatementProxy statement, boolean firstResult, int... updateCountArray) {
|
||||
private final void internalAfterStatementExecute(StatementProxy statement, boolean firstResult,
|
||||
int... updateCountArray) {
|
||||
|
||||
final JdbcStatementStat.Entry entry = getStatementInfo(statement);
|
||||
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
package com.alibaba.druid.pool;
|
||||
|
||||
import java.sql.SQLException;
|
||||
|
||||
public class DataSourceClosedException extends SQLException {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
public DataSourceClosedException(){
|
||||
super();
|
||||
}
|
||||
|
||||
public DataSourceClosedException(String reason){
|
||||
super(reason);
|
||||
}
|
||||
|
||||
public DataSourceClosedException(Throwable cause){
|
||||
super(cause);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -72,7 +72,7 @@ import com.alibaba.druid.util.JdbcUtils;
|
||||
*/
|
||||
public class DruidDataSource extends DruidAbstractDataSource implements DruidDataSourceMBean, ManagedDataSource, Referenceable, Closeable, Cloneable, ConnectionPoolDataSource {
|
||||
|
||||
public final static Log LOG = LogFactory.getLog(DruidDataSource.class);
|
||||
private final static Log LOG = LogFactory.getLog(DruidDataSource.class);
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@@ -117,6 +117,7 @@ public class DruidDataSource extends DruidAbstractDataSource implements DruidDat
|
||||
private String initStackTrace;
|
||||
|
||||
private boolean closed = false;
|
||||
private long closeTimeMillis = -1L;
|
||||
|
||||
private JdbcDataSourceStat dataSourceStat;
|
||||
|
||||
@@ -274,23 +275,23 @@ public class DruidDataSource extends DruidAbstractDataSource implements DruidDat
|
||||
if (this.driverClass != null) {
|
||||
this.driverClass = driverClass.trim();
|
||||
}
|
||||
|
||||
|
||||
if (isTestOnBorrow() || isTestOnReturn() || isTestWhileIdle()) {
|
||||
if (this.getValidationQuery() == null || this.getValidationQuery().length() == 0) {
|
||||
String errorMessage = "";
|
||||
|
||||
|
||||
if (isTestOnBorrow()) {
|
||||
errorMessage += "testOnBorrow is true, ";
|
||||
}
|
||||
|
||||
|
||||
if (isTestOnReturn()) {
|
||||
errorMessage += "testOnReturn is true, ";
|
||||
}
|
||||
|
||||
|
||||
if (isTestWhileIdle()) {
|
||||
errorMessage += "testWhileIdle is true, ";
|
||||
}
|
||||
|
||||
|
||||
LOG.error(errorMessage + "validationQuery not set");
|
||||
}
|
||||
}
|
||||
@@ -301,9 +302,9 @@ public class DruidDataSource extends DruidAbstractDataSource implements DruidDat
|
||||
if (jdbcUrl.startsWith(DruidDriver.DEFAULT_PREFIX)) {
|
||||
DataSourceProxyConfig config = DruidDriver.parseConfig(jdbcUrl, null);
|
||||
this.driverClass = config.getRawDriverClassName();
|
||||
|
||||
|
||||
LOG.error("error url : '" + jdbcUrl + "', it should be : '" + config.getRawUrl() + "'");
|
||||
|
||||
|
||||
this.jdbcUrl = config.getRawUrl();
|
||||
if (this.name == null) {
|
||||
this.name = config.getName();
|
||||
@@ -366,7 +367,7 @@ public class DruidDataSource extends DruidAbstractDataSource implements DruidDat
|
||||
} else if (realDriverClassName.equals("com.alibaba.druid.mock.MockDriver")) {
|
||||
this.exceptionSorter = new MockExceptionSorter();
|
||||
}
|
||||
|
||||
|
||||
if (realDriverClassName.equals("com.mysql.jdbc.Driver")) {
|
||||
if (this.isPoolPreparedStatements()) {
|
||||
LOG.error("mysql should not use 'PoolPreparedStatements'");
|
||||
@@ -554,6 +555,11 @@ public class DruidDataSource extends DruidAbstractDataSource implements DruidDat
|
||||
}
|
||||
|
||||
try {
|
||||
if (closed) {
|
||||
connectErrorCount.incrementAndGet();
|
||||
throw new DataSourceClosedException("dataSource already closed at " + new Date(closeTimeMillis));
|
||||
}
|
||||
|
||||
if (!enable) {
|
||||
connectErrorCount.incrementAndGet();
|
||||
throw new DataSourceDisableException();
|
||||
@@ -775,6 +781,7 @@ public class DruidDataSource extends DruidAbstractDataSource implements DruidDat
|
||||
notEmptySignalCount++;
|
||||
|
||||
this.closed = true;
|
||||
this.closeTimeMillis = System.currentTimeMillis();
|
||||
|
||||
for (Filter filter : filters) {
|
||||
filter.destory();
|
||||
@@ -782,6 +789,8 @@ public class DruidDataSource extends DruidAbstractDataSource implements DruidDat
|
||||
} finally {
|
||||
lock.unlock();
|
||||
}
|
||||
|
||||
LOG.warn("dataSource " + this.getID() + " closed");
|
||||
}
|
||||
|
||||
void incrementCreateCount() {
|
||||
@@ -879,7 +888,8 @@ public class DruidDataSource extends DruidAbstractDataSource implements DruidDat
|
||||
if (createError != null) {
|
||||
throw new GetConnectionTimeoutException(createError);
|
||||
} else {
|
||||
throw new GetConnectionTimeoutException("loopWaitCount " + i + ", wait millis " + (nanos - estimate)/(1000 * 1000));
|
||||
throw new GetConnectionTimeoutException("loopWaitCount " + i + ", wait millis "
|
||||
+ (nanos - estimate) / (1000 * 1000));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1105,11 +1115,11 @@ public class DruidDataSource extends DruidAbstractDataSource implements DruidDat
|
||||
for (; iter.hasNext();) {
|
||||
Map.Entry<DruidPooledConnection, ActiveConnectionTraceInfo> entry = iter.next();
|
||||
DruidPooledConnection pooledConnection = entry.getKey();
|
||||
|
||||
|
||||
if (pooledConnection.isRunning()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
ActiveConnectionTraceInfo activeInfo = entry.getValue();
|
||||
long timeMillis = currentMillis - activeInfo.getConnectTime();
|
||||
|
||||
@@ -1447,15 +1457,15 @@ public class DruidDataSource extends DruidAbstractDataSource implements DruidDat
|
||||
PreparedStatementPool stmtPool = connHolder.getStatementPool();
|
||||
for (PreparedStatementHolder stmtHolder : stmtPool.getMap().values()) {
|
||||
Map<String, Object> stmtInfo = new LinkedHashMap<String, Object>();
|
||||
|
||||
|
||||
stmtInfo.put("sql", stmtHolder.getKey().getSql());
|
||||
stmtInfo.put("defaultRowPretch", stmtHolder.getDefaultRowPretch());
|
||||
stmtInfo.put("rowPrefetch", stmtHolder.getRowPrefetch());
|
||||
stmtInfo.put("hitCount", stmtHolder.getHitCount());
|
||||
|
||||
|
||||
stmtCache.add(stmtInfo);
|
||||
}
|
||||
|
||||
|
||||
map.put("pscache", stmtCache);
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,204 @@
|
||||
package com.alibaba.druid.stat;
|
||||
|
||||
import java.sql.Driver;
|
||||
import java.sql.DriverManager;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Enumeration;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import javax.management.JMException;
|
||||
|
||||
import com.alibaba.druid.VERSION;
|
||||
import com.alibaba.druid.pool.DruidDataSource;
|
||||
|
||||
public class DruidDataSourceStatDefaultStrategy implements DruidDataSourceStatStrategy {
|
||||
|
||||
private Set<DruidDataSource> getDruidDataSourceInstances() {
|
||||
return DruidDataSourceStatManager.getDruidDataSourceInstances();
|
||||
}
|
||||
|
||||
public void resetDataSourceStat() {
|
||||
DruidDataSourceStatManager.getInstance().reset();
|
||||
}
|
||||
|
||||
public void resetSqlStat() {
|
||||
JdbcStatManager.getInstance().reset();
|
||||
}
|
||||
|
||||
public void resetAll() {
|
||||
resetSqlStat();
|
||||
resetDataSourceStat();
|
||||
}
|
||||
|
||||
private JdbcSqlStat getSqlStatById(Integer id) {
|
||||
|
||||
for (DruidDataSource ds : getDruidDataSourceInstances()) {
|
||||
JdbcSqlStat sqlStat = ds.getDataSourceStat().getSqlStat(id);
|
||||
if (sqlStat != null)
|
||||
return sqlStat;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public Map<String, Object> getDataSourceStatData(Integer id) {
|
||||
if (id == null) {
|
||||
return null;
|
||||
}
|
||||
DruidDataSource datasource = getDruidDataSourceById(id);
|
||||
return datasource == null ? null : dataSourceToMapData(datasource);
|
||||
}
|
||||
|
||||
private DruidDataSource getDruidDataSourceById(Integer identity) {
|
||||
|
||||
if (identity == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
for (DruidDataSource datasource : getDruidDataSourceInstances()) {
|
||||
if (System.identityHashCode(datasource) == identity) {
|
||||
return datasource;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public List<Map<String, Object>> getSqlStatDataList() {
|
||||
List<Map<String, Object>> result = new ArrayList<Map<String, Object>>();
|
||||
for (DruidDataSource datasource : getDruidDataSourceInstances()) {
|
||||
for (JdbcSqlStat sqlStat : datasource.getDataSourceStat().getSqlStatMap().values()) {
|
||||
if (sqlStat.getExecuteCount() == 0 && sqlStat.getRunningCount() == 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
result.add(getSqlStatData(sqlStat));
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public Map<String, Object> getSqlStatData(Integer id) {
|
||||
if (id == null) {
|
||||
return null;
|
||||
}
|
||||
JdbcSqlStat sqlStat = getSqlStatById(id);
|
||||
return sqlStat == null ? null : getSqlStatData(sqlStat);
|
||||
}
|
||||
|
||||
private Map<String, Object> getSqlStatData(JdbcSqlStat sqlStat) {
|
||||
try {
|
||||
return sqlStat.getData();
|
||||
} catch (JMException e) {
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public List<Object> getDataSourceStatList() {
|
||||
List<Object> datasourceList = new ArrayList<Object>();
|
||||
for (DruidDataSource dataSource : getDruidDataSourceInstances()) {
|
||||
datasourceList.add(dataSourceToMapData(dataSource));
|
||||
}
|
||||
return datasourceList;
|
||||
}
|
||||
|
||||
public Map<String, Object> returnJSONBasicStat() {
|
||||
Map<String, Object> dataMap = new LinkedHashMap<String, Object>();
|
||||
dataMap.put("Version", VERSION.getVersionNumber());
|
||||
dataMap.put("Drivers", getDriversData());
|
||||
return dataMap;
|
||||
}
|
||||
|
||||
private List<String> getDriversData() {
|
||||
List<String> drivers = new ArrayList<String>();
|
||||
for (Enumeration<Driver> e = DriverManager.getDrivers(); e.hasMoreElements();) {
|
||||
Driver driver = e.nextElement();
|
||||
drivers.add(driver.getClass().getName());
|
||||
}
|
||||
return drivers;
|
||||
}
|
||||
|
||||
public List<Map<String, Object>> getPoolingConnectionInfoByDataSourceId(Integer id) {
|
||||
DruidDataSource datasource = getDruidDataSourceById(id);
|
||||
if (datasource == null)
|
||||
return null;
|
||||
return datasource.getPoolingConnectionInfo();
|
||||
}
|
||||
|
||||
public List<String> getActiveConnectionStackTraceByDataSourceId(Integer id) {
|
||||
DruidDataSource datasource = getDruidDataSourceById(id);
|
||||
if (datasource == null || !datasource.isRemoveAbandoned())
|
||||
return null;
|
||||
|
||||
return datasource.getActiveConnectionStackTrace();
|
||||
}
|
||||
|
||||
private Map<String, Object> dataSourceToMapData(DruidDataSource dataSource) {
|
||||
|
||||
Map<String, Object> dataMap = new LinkedHashMap<String, Object>();
|
||||
dataMap.put("Identity", System.identityHashCode(dataSource));
|
||||
dataMap.put("Name", dataSource.getName());
|
||||
dataMap.put("DbType", dataSource.getDbType());
|
||||
dataMap.put("DriverClassName", dataSource.getDriverClassName());
|
||||
|
||||
dataMap.put("URL", dataSource.getUrl());
|
||||
dataMap.put("UserName", dataSource.getUsername());
|
||||
dataMap.put("FilterClassNames", dataSource.getFilterClassNames());
|
||||
|
||||
dataMap.put("WaitThreadCount", dataSource.getWaitThreadCount());
|
||||
dataMap.put("NotEmptyWaitCount", dataSource.getNotEmptyWaitCount());
|
||||
dataMap.put("NotEmptyWaitMillis", dataSource.getNotEmptyWaitMillis());
|
||||
|
||||
dataMap.put("PoolingCount", dataSource.getPoolingCount());
|
||||
dataMap.put("PoolingPeak", dataSource.getPoolingPeak());
|
||||
dataMap.put("PoolingPeakTime", dataSource.getPoolingPeakTime() == null ? null : dataSource.getPoolingPeakTime().toString());
|
||||
|
||||
dataMap.put("ActiveCount", dataSource.getActiveCount());
|
||||
dataMap.put("ActivePeak", dataSource.getActivePeak());
|
||||
dataMap.put("ActivePeakTime", dataSource.getActivePeakTime() == null ? null : dataSource.getActivePeakTime().toString());
|
||||
|
||||
dataMap.put("InitialSize", dataSource.getInitialSize());
|
||||
dataMap.put("MinIdle", dataSource.getMinIdle());
|
||||
dataMap.put("MaxActive", dataSource.getMaxActive());
|
||||
|
||||
dataMap.put("QueryTimeout", dataSource.getQueryTimeout());
|
||||
dataMap.put("TransactionQueryTimeout", dataSource.getTransactionQueryTimeout());
|
||||
dataMap.put("LoginTimeout", dataSource.getLoginTimeout());
|
||||
dataMap.put("ValidConnectionCheckerClassName", dataSource.getValidConnectionCheckerClassName());
|
||||
dataMap.put("ExceptionSorterClassName", dataSource.getExceptionSorterClassName());
|
||||
|
||||
dataMap.put("TestOnBorrow", dataSource.isTestOnBorrow());
|
||||
dataMap.put("TestOnReturn", dataSource.isTestOnReturn());
|
||||
dataMap.put("TestWhileIdle", dataSource.isTestWhileIdle());
|
||||
|
||||
dataMap.put("DefaultAutoCommit", dataSource.isDefaultAutoCommit());
|
||||
dataMap.put("DefaultReadOnly", dataSource.isDefaultAutoCommit());
|
||||
dataMap.put("DefaultTransactionIsolation", dataSource.getDefaultTransactionIsolation());
|
||||
|
||||
dataMap.put("LogicConnectCount", dataSource.getConnectCount());
|
||||
dataMap.put("LogicCloseCount", dataSource.getCloseCount());
|
||||
dataMap.put("LogicConnectErrorCount", dataSource.getConnectErrorCount());
|
||||
|
||||
dataMap.put("PhysicalConnectCount", dataSource.getCreateCount());
|
||||
dataMap.put("PhysicalCloseCount", dataSource.getDestroyCount());
|
||||
dataMap.put("PhysicalConnectErrorCount", dataSource.getCreateErrorCount());
|
||||
|
||||
dataMap.put("ExecuteCount", dataSource.getExecuteCount());
|
||||
dataMap.put("ErrorCount", dataSource.getErrorCount());
|
||||
dataMap.put("CommitCount", dataSource.getCommitCount());
|
||||
dataMap.put("RollbackCount", dataSource.getRollbackCount());
|
||||
|
||||
dataMap.put("PSCacheAccessCount", dataSource.getCachedPreparedStatementAccessCount());
|
||||
dataMap.put("PSCacheHitCount", dataSource.getCachedPreparedStatementHitCount());
|
||||
dataMap.put("PSCacheMissCount", dataSource.getCachedPreparedStatementMissCount());
|
||||
|
||||
dataMap.put("StartTransactionCount", dataSource.getStartTransactionCount());
|
||||
dataMap.put("TransactionHistogram", dataSource.getTransactionHistogramValues());
|
||||
|
||||
dataMap.put("ConnectionHoldTimeHistogram", dataSource.getDataSourceStat().getConnectionHoldHistogram().toArray());
|
||||
dataMap.put("RemoveAbandoned", dataSource.isRemoveAbandoned());
|
||||
|
||||
return dataMap;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
package com.alibaba.druid.stat;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import com.alibaba.druid.util.ReflectionUtils;
|
||||
|
||||
public class DruidDataSourceStatJNDIStatStrategy implements DruidDataSourceStatStrategy{
|
||||
|
||||
private Object getStrategyB() {
|
||||
return ReflectionUtils.getClassFromWebContainerOrCurrentClassLoader("com.alibaba.druid.stat.DruidDataSourceStatDefaultStrategy");
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public Map<String, Object> getSqlStatData(Integer id) {
|
||||
return (Map<String, Object>) ReflectionUtils.callObjectMethod(getStrategyB(), "getSqlStatData", id);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public List<Map<String, Object>> getSqlStatDataList() {
|
||||
return (List<Map<String, Object>>) ReflectionUtils.callObjectMethod(getStrategyB(), "getSqlStatDataList");
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public List<String> getActiveConnectionStackTraceByDataSourceId(Integer id) {
|
||||
return (List<String>) ReflectionUtils.callObjectMethod(getStrategyB(), "getActiveConnectionStackTraceByDataSourceId", id);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public Map<String, Object> returnJSONBasicStat() {
|
||||
return (Map<String, Object>) ReflectionUtils.callObjectMethod(getStrategyB(), "returnJSONBasicStat");
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public List<Object> getDataSourceStatList() {
|
||||
return (List<Object>) ReflectionUtils.callObjectMethod(getStrategyB(), "getDataSourceStatList");
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public Map<String, Object> getDataSourceStatData(Integer id) {
|
||||
return (Map<String, Object>) ReflectionUtils.callObjectMethod(getStrategyB(), "getDataSourceStatData", id);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public List<Map<String, Object>> getPoolingConnectionInfoByDataSourceId(Integer id) {
|
||||
return (List<Map<String, Object>>) ReflectionUtils.callObjectMethod(getStrategyB(), "getPoolingConnectionInfoByDataSourceId", id);
|
||||
}
|
||||
|
||||
public void resetAll() {
|
||||
ReflectionUtils.callObjectMethod(getStrategyB(), "resetAll");
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
package com.alibaba.druid.stat;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public interface DruidDataSourceStatStrategy {
|
||||
public Map<String, Object> getSqlStatData(Integer id);
|
||||
|
||||
public List<Map<String, Object>> getSqlStatDataList();
|
||||
|
||||
public List<String> getActiveConnectionStackTraceByDataSourceId(Integer id);
|
||||
|
||||
public Map<String, Object> returnJSONBasicStat();
|
||||
|
||||
public List<Object> getDataSourceStatList();
|
||||
|
||||
public Map<String, Object> getDataSourceStatData(Integer id);
|
||||
|
||||
public List<Map<String, Object>> getPoolingConnectionInfoByDataSourceId(Integer id);
|
||||
|
||||
public void resetAll();
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
package com.alibaba.druid.stat;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class DruidDataSourceStatStrategyContext {
|
||||
private DruidDataSourceStatStrategy druidDataSourceStatStrategy;
|
||||
|
||||
public DruidDataSourceStatStrategyContext(DruidDataSourceStatStrategy druidDataSourceStatStrategy) {
|
||||
this.druidDataSourceStatStrategy = druidDataSourceStatStrategy;
|
||||
}
|
||||
|
||||
public Map<String, Object> getSqlStatData(Integer id) {
|
||||
return druidDataSourceStatStrategy.getSqlStatData(id);
|
||||
}
|
||||
|
||||
public List<Map<String, Object>> getSqlStatDataList() {
|
||||
return druidDataSourceStatStrategy.getSqlStatDataList();
|
||||
}
|
||||
|
||||
public List<String> getActiveConnectionStackTraceByDataSourceId(Integer id) {
|
||||
return druidDataSourceStatStrategy.getActiveConnectionStackTraceByDataSourceId(id);
|
||||
}
|
||||
|
||||
public Map<String, Object> returnJSONBasicStat() {
|
||||
return druidDataSourceStatStrategy.returnJSONBasicStat();
|
||||
}
|
||||
|
||||
public List<Object> getDataSourceStatList() {
|
||||
return druidDataSourceStatStrategy.getDataSourceStatList();
|
||||
}
|
||||
|
||||
public Map<String, Object> getDataSourceStatData(Integer id) {
|
||||
return druidDataSourceStatStrategy.getDataSourceStatData(id);
|
||||
}
|
||||
|
||||
public List<Map<String, Object>> getPoolingConnectionInfoByDataSourceId(Integer id) {
|
||||
return druidDataSourceStatStrategy.getPoolingConnectionInfoByDataSourceId(id);
|
||||
}
|
||||
|
||||
public void resetAll() {
|
||||
druidDataSourceStatStrategy.resetAll();
|
||||
}
|
||||
}
|
||||
@@ -1,252 +1,67 @@
|
||||
package com.alibaba.druid.stat;
|
||||
|
||||
import java.sql.Driver;
|
||||
import java.sql.DriverManager;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Enumeration;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.locks.ReentrantLock;
|
||||
|
||||
import javax.management.JMException;
|
||||
|
||||
import com.alibaba.druid.VERSION;
|
||||
import com.alibaba.druid.pool.DruidDataSource;
|
||||
import com.alibaba.druid.util.ReflectionUtils;
|
||||
|
||||
/**
|
||||
* 监控相关的对外数据暴露
|
||||
*
|
||||
* <pre>
|
||||
* 1. 为了支持jndi数据源本类内部调用druid相关对象均需要反射调用,返回值也应该是Object,List<Object>,Map<String,Object>等无关于druid的类型
|
||||
* 2. 对外暴露的public方法都应该先调用init(),应该有更好的方式,暂时没想到
|
||||
* </pre>
|
||||
*
|
||||
* @author sandzhang<sandzhangtoo@gmail.com>
|
||||
*/
|
||||
public class DruidStatManagerFacade {
|
||||
|
||||
private final static DruidStatManagerFacade instance = new DruidStatManagerFacade();
|
||||
private final static DruidStatManagerFacade instance = new DruidStatManagerFacade();
|
||||
|
||||
private boolean inited = false;
|
||||
private static DruidDataSourceStatStrategyContext ctx = null;
|
||||
|
||||
protected final ReentrantLock lock = new ReentrantLock(true);
|
||||
private static DruidDataSourceStatStrategy strategy = null;
|
||||
|
||||
private DruidDataSourceStatManager druidDataSourceStatManager;
|
||||
private JdbcStatManager jdbcStatManager;
|
||||
static {
|
||||
strategy = new DruidDataSourceStatJNDIStatStrategy();
|
||||
ctx = new DruidDataSourceStatStrategyContext(strategy);
|
||||
}
|
||||
|
||||
private Set<DruidDataSource> datasourceInstances;
|
||||
private DruidStatManagerFacade() {
|
||||
}
|
||||
|
||||
private DruidStatManagerFacade() {
|
||||
}
|
||||
public static DruidStatManagerFacade getInstance() {
|
||||
return instance;
|
||||
}
|
||||
|
||||
public static DruidStatManagerFacade getInstance() {
|
||||
return instance;
|
||||
}
|
||||
public Map<String, Object> getSqlStatData(Integer id) {
|
||||
return ctx.getSqlStatData(id);
|
||||
}
|
||||
|
||||
private void init() {
|
||||
if (inited) {
|
||||
return;
|
||||
}
|
||||
public List<Map<String, Object>> getSqlStatDataList() {
|
||||
return ctx.getSqlStatDataList();
|
||||
}
|
||||
|
||||
lock.lock();
|
||||
try {
|
||||
if (inited) {
|
||||
return;
|
||||
}
|
||||
public List<String> getActiveConnectionStackTraceByDataSourceId(Integer id) {
|
||||
return ctx.getActiveConnectionStackTraceByDataSourceId(id);
|
||||
}
|
||||
|
||||
initByClassLoader();
|
||||
public Map<String, Object> returnJSONBasicStat() {
|
||||
return ctx.returnJSONBasicStat();
|
||||
}
|
||||
|
||||
inited = true;
|
||||
} finally {
|
||||
lock.unlock();
|
||||
}
|
||||
}
|
||||
public List<Object> getDataSourceStatList() {
|
||||
return ctx.getDataSourceStatList();
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private void initByClassLoader() {
|
||||
Class<?> druidDataSourceStatManagerClass = ReflectionUtils.getClassFromWebContainerOrCurrentClassLoader("com.alibaba.druid.stat.DruidDataSourceStatManager");
|
||||
public Map<String, Object> getDataSourceStatData(Integer id) {
|
||||
return ctx.getDataSourceStatData(id);
|
||||
}
|
||||
|
||||
druidDataSourceStatManager = (DruidDataSourceStatManager) ReflectionUtils.callStaticMethod(druidDataSourceStatManagerClass,
|
||||
"getInstance");
|
||||
datasourceInstances = (Set<DruidDataSource>) ReflectionUtils.callStaticMethod(druidDataSourceStatManagerClass,
|
||||
"getDruidDataSourceInstances");
|
||||
public List<Map<String, Object>> getPoolingConnectionInfoByDataSourceId(Integer id) {
|
||||
return ctx.getPoolingConnectionInfoByDataSourceId(id);
|
||||
}
|
||||
|
||||
Class<?> jdbcStatManagerClass = ReflectionUtils.getClassFromWebContainerOrCurrentClassLoader("com.alibaba.druid.stat.JdbcStatManager");
|
||||
jdbcStatManager = (JdbcStatManager) ReflectionUtils.callStaticMethod(jdbcStatManagerClass, "getInstance");
|
||||
|
||||
}
|
||||
|
||||
public Set<DruidDataSource> getDruidDataSourceInstances() {
|
||||
init();
|
||||
return datasourceInstances;
|
||||
}
|
||||
|
||||
public void resetDataSourceStat() {
|
||||
init();
|
||||
druidDataSourceStatManager.reset();
|
||||
}
|
||||
|
||||
public void resetSqlStat() {
|
||||
init();
|
||||
jdbcStatManager.reset();
|
||||
}
|
||||
|
||||
public void resetAll() {
|
||||
init();
|
||||
resetSqlStat();
|
||||
resetDataSourceStat();
|
||||
}
|
||||
|
||||
public JdbcSqlStat getSqlStatById(Integer id) {
|
||||
init();
|
||||
|
||||
for (DruidDataSource ds : getDruidDataSourceInstances()) {
|
||||
JdbcSqlStat sqlStat = ds.getDataSourceStat().getSqlStat(id);
|
||||
if (sqlStat != null) return sqlStat;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public Map<String, Object> getDataSourceStatData(Integer id) {
|
||||
if (id == null) {
|
||||
return null;
|
||||
}
|
||||
DruidDataSource datasource = getDruidDataSourceById(id);
|
||||
return datasource == null ? null : dataSourceToMapData(datasource);
|
||||
}
|
||||
|
||||
public DruidDataSource getDruidDataSourceById(Integer identity) {
|
||||
init();
|
||||
|
||||
if (identity == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
for (DruidDataSource datasource : getDruidDataSourceInstances()) {
|
||||
if (System.identityHashCode(datasource) == identity) {
|
||||
return datasource;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public Map<String, Object> getSqlStatData(Integer id) {
|
||||
if (id == null) {
|
||||
return null;
|
||||
}
|
||||
JdbcSqlStat sqlStat = getSqlStatById(id);
|
||||
return sqlStat == null ? null : getSqlStatData(sqlStat);
|
||||
}
|
||||
|
||||
public Map<String, Object> getSqlStatData(JdbcSqlStat sqlStat) {
|
||||
try {
|
||||
return sqlStat.getData();
|
||||
} catch (JMException e) {
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public List<Object> getDataSourceStatList() {
|
||||
List<Object> datasourceList = new ArrayList<Object>();
|
||||
for (DruidDataSource dataSource : getDruidDataSourceInstances()) {
|
||||
datasourceList.add(dataSourceToMapData(dataSource));
|
||||
}
|
||||
return datasourceList;
|
||||
}
|
||||
|
||||
public Map<String, Object> returnJSONBasicStat() {
|
||||
Map<String, Object> dataMap = new LinkedHashMap<String, Object>();
|
||||
dataMap.put("Version", VERSION.getVersionNumber());
|
||||
dataMap.put("Drivers", getDriversData());
|
||||
return dataMap;
|
||||
}
|
||||
|
||||
private List<String> getDriversData() {
|
||||
List<String> drivers = new ArrayList<String>();
|
||||
for (Enumeration<Driver> e = DriverManager.getDrivers(); e.hasMoreElements();) {
|
||||
Driver driver = e.nextElement();
|
||||
drivers.add(driver.getClass().getName());
|
||||
}
|
||||
return drivers;
|
||||
}
|
||||
|
||||
public List<Map<String, Object>> getPoolingConnectionInfoByDataSourceId(Integer id) {
|
||||
DruidDataSource datasource = getDruidDataSourceById(id);
|
||||
if (datasource == null) return null;
|
||||
return datasource.getPoolingConnectionInfo();
|
||||
}
|
||||
|
||||
public List<String> getActiveConnectionStackTraceByDataSourceId(Integer id) {
|
||||
DruidDataSource datasource = getDruidDataSourceById(id);
|
||||
if (datasource == null || !datasource.isRemoveAbandoned()) return null;
|
||||
|
||||
return datasource.getActiveConnectionStackTrace();
|
||||
}
|
||||
|
||||
private Map<String, Object> dataSourceToMapData(DruidDataSource dataSource) {
|
||||
|
||||
Map<String, Object> dataMap = new LinkedHashMap<String, Object>();
|
||||
dataMap.put("Identity", System.identityHashCode(dataSource));
|
||||
dataMap.put("Name", dataSource.getName());
|
||||
dataMap.put("DbType", dataSource.getDbType());
|
||||
dataMap.put("DriverClassName", dataSource.getDriverClassName());
|
||||
|
||||
dataMap.put("URL", dataSource.getUrl());
|
||||
dataMap.put("UserName", dataSource.getUsername());
|
||||
dataMap.put("FilterClassNames", dataSource.getFilterClassNames());
|
||||
|
||||
dataMap.put("WaitThreadCount", dataSource.getWaitThreadCount());
|
||||
dataMap.put("NotEmptyWaitCount", dataSource.getNotEmptyWaitCount());
|
||||
dataMap.put("NotEmptyWaitMillis", dataSource.getNotEmptyWaitMillis());
|
||||
|
||||
dataMap.put("PoolingCount", dataSource.getPoolingCount());
|
||||
dataMap.put("PoolingPeak", dataSource.getPoolingPeak());
|
||||
dataMap.put("PoolingPeakTime",
|
||||
dataSource.getPoolingPeakTime() == null ? null : dataSource.getPoolingPeakTime().toString());
|
||||
|
||||
dataMap.put("ActiveCount", dataSource.getActiveCount());
|
||||
dataMap.put("ActivePeak", dataSource.getActivePeak());
|
||||
dataMap.put("ActivePeakTime",
|
||||
dataSource.getActivePeakTime() == null ? null : dataSource.getActivePeakTime().toString());
|
||||
|
||||
dataMap.put("InitialSize", dataSource.getInitialSize());
|
||||
dataMap.put("MinIdle", dataSource.getMinIdle());
|
||||
dataMap.put("MaxActive", dataSource.getMaxActive());
|
||||
|
||||
dataMap.put("QueryTimeout", dataSource.getQueryTimeout());
|
||||
dataMap.put("TransactionQueryTimeout", dataSource.getTransactionQueryTimeout());
|
||||
dataMap.put("LoginTimeout", dataSource.getLoginTimeout());
|
||||
dataMap.put("ValidConnectionCheckerClassName", dataSource.getValidConnectionCheckerClassName());
|
||||
dataMap.put("ExceptionSorterClassName", dataSource.getExceptionSorterClassName());
|
||||
|
||||
dataMap.put("TestOnBorrow", dataSource.isTestOnBorrow());
|
||||
dataMap.put("TestOnReturn", dataSource.isTestOnReturn());
|
||||
dataMap.put("TestWhileIdle", dataSource.isTestWhileIdle());
|
||||
|
||||
dataMap.put("DefaultAutoCommit", dataSource.isDefaultAutoCommit());
|
||||
dataMap.put("DefaultReadOnly", dataSource.isDefaultAutoCommit());
|
||||
dataMap.put("DefaultTransactionIsolation", dataSource.getDefaultTransactionIsolation());
|
||||
|
||||
dataMap.put("LogicConnectCount", dataSource.getConnectCount());
|
||||
dataMap.put("LogicCloseCount", dataSource.getCloseCount());
|
||||
dataMap.put("LogicConnectErrorCount", dataSource.getConnectErrorCount());
|
||||
|
||||
dataMap.put("PhysicalConnectCount", dataSource.getCreateCount());
|
||||
dataMap.put("PhysicalCloseCount", dataSource.getDestroyCount());
|
||||
dataMap.put("PhysicalConnectErrorCount", dataSource.getCreateErrorCount());
|
||||
|
||||
dataMap.put("ExecuteCount", dataSource.getExecuteCount());
|
||||
dataMap.put("ErrorCount", dataSource.getErrorCount());
|
||||
dataMap.put("CommitCount", dataSource.getCommitCount());
|
||||
dataMap.put("RollbackCount", dataSource.getRollbackCount());
|
||||
|
||||
dataMap.put("PSCacheAccessCount", dataSource.getCachedPreparedStatementAccessCount());
|
||||
dataMap.put("PSCacheHitCount", dataSource.getCachedPreparedStatementHitCount());
|
||||
dataMap.put("PSCacheMissCount", dataSource.getCachedPreparedStatementMissCount());
|
||||
|
||||
dataMap.put("StartTransactionCount", dataSource.getStartTransactionCount());
|
||||
dataMap.put("TransactionHistogram", dataSource.getTransactionHistogramValues());
|
||||
|
||||
dataMap.put("ConnectionHoldTimeHistogram",
|
||||
dataSource.getDataSourceStat().getConnectionHoldHistogram().toArray());
|
||||
dataMap.put("RemoveAbandoned", dataSource.isRemoveAbandoned());
|
||||
|
||||
return dataMap;
|
||||
}
|
||||
public void resetAll() {
|
||||
ctx.resetAll();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -490,10 +490,14 @@ public final class JdbcSqlStat implements JdbcSqlStatMBean {
|
||||
|
||||
// 25 - 29
|
||||
"Histogram", //
|
||||
"LastSlowParameters", "ResultSetHoldTime", "ExecuteAndResultSetHoldTime", "FetchRowCountHistogram",
|
||||
"LastSlowParameters", //
|
||||
"ResultSetHoldTime", //
|
||||
"ExecuteAndResultSetHoldTime", //
|
||||
"FetchRowCountHistogram", //
|
||||
|
||||
// 30
|
||||
"EffectedRowCountHistogram", "ExecuteAndResultHoldTimeHistogram"
|
||||
"EffectedRowCountHistogram", //
|
||||
"ExecuteAndResultHoldTimeHistogram"
|
||||
|
||||
//
|
||||
};
|
||||
|
||||
@@ -1,19 +1,18 @@
|
||||
package com.alibaba.druid.support;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import com.alibaba.druid.pool.DruidDataSource;
|
||||
import com.alibaba.druid.stat.DruidStatManagerFacade;
|
||||
import com.alibaba.druid.stat.JdbcSqlStat;
|
||||
import com.alibaba.druid.util.MapComparator;
|
||||
import com.alibaba.druid.util.StringUtils;
|
||||
import com.alibaba.fastjson.JSON;
|
||||
|
||||
/**
|
||||
* 注意:避免直接调用Druid相关对象例如DruidDataSource等,相关调用要到DruidStatManagerFacade里用反射实现
|
||||
*
|
||||
* @author sandzhang<sandzhangtoo@gmail.com>
|
||||
*/
|
||||
public class JSONDruidStatService {
|
||||
@@ -96,16 +95,7 @@ public class JSONDruidStatService {
|
||||
if (page == null) page = DEFAULT_PAGE;
|
||||
if (perPageCount == null) perPageCount = DEFAULT_PER_PAGE_COUNT;
|
||||
|
||||
List<Map<String, Object>> array = new ArrayList<Map<String, Object>>();
|
||||
for (DruidDataSource datasource : druidStatManager.getDruidDataSourceInstances()) {
|
||||
for (JdbcSqlStat sqlStat : datasource.getDataSourceStat().getSqlStatMap().values()) {
|
||||
if (sqlStat.getExecuteCount() == 0 && sqlStat.getRunningCount() == 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
array.add(druidStatManager.getSqlStatData(sqlStat));
|
||||
}
|
||||
}
|
||||
List<Map<String, Object>> array = druidStatManager.getSqlStatDataList();
|
||||
|
||||
// orderby
|
||||
if (orderBy != null && orderBy.trim().length() != 0) {
|
||||
|
||||
@@ -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 {
|
||||
@@ -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) {
|
||||
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'>MaxTimespanOccurTime</td>");
|
||||
content.append("<td>" + format.format(sqlStat.getExecuteNanoSpanMaxOccurTime()) + "</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.getLastSlowParameters() + "</td>");
|
||||
content.append("<td>" + sqlStat.get("LastSlowParameters") + "</td>");
|
||||
content.append("</tr>");
|
||||
content.append("</table>");
|
||||
content.append("<br />");
|
||||
}
|
||||
|
||||
List<SQLStatement> statementList = SQLUtils.parseStatements(sqlStat.getSql(), sqlStat.getDbType());
|
||||
|
||||
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>");
|
||||
|
||||
@@ -4,21 +4,28 @@ import java.lang.reflect.Method;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
|
||||
import com.alibaba.druid.support.logging.Log;
|
||||
import com.alibaba.druid.support.logging.LogFactory;
|
||||
|
||||
/**
|
||||
* @author sandzhang<sandzhangtoo@gmail.com>
|
||||
*/
|
||||
public class ReflectionUtils {
|
||||
|
||||
private final static Log LOG = LogFactory.getLog(ReflectionUtils.class);
|
||||
|
||||
public static Class<?> getClassFromWebContainerOrCurrentClassLoader(String className) {
|
||||
Class<?> result = null;
|
||||
try {
|
||||
result = HttpServletRequest.class.getClassLoader().loadClass(className);
|
||||
} catch (ClassNotFoundException e) {
|
||||
if (LOG.isDebugEnabled()) LOG.debug("can'r find class in web container classLoader ", e);
|
||||
}
|
||||
if (result == null) {
|
||||
try {
|
||||
result = Thread.currentThread().getContextClassLoader().loadClass(className);
|
||||
} catch (ClassNotFoundException e) {
|
||||
LOG.error("can'r find class in current thread context classLoader ", e);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
@@ -30,16 +37,28 @@ public class ReflectionUtils {
|
||||
Method m = classObject.getMethod(methodName);
|
||||
return m.invoke(classObject);
|
||||
} catch (Exception e) {
|
||||
LOG.warn("callStaticMethod fail:class=" + classObject.getName() + " method=" + methodName, e);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public static String getTest() {
|
||||
return "test";
|
||||
public static Object callObjectMethod(Object obj, String methodName, Object... methodParams) {
|
||||
try {
|
||||
Method m = obj.getClass().getMethod(methodName);
|
||||
return m.invoke(obj, methodParams);
|
||||
} catch (Exception e) {
|
||||
LOG.warn("callObjectMethod fail:class=" + obj.getClass().getName() + " method=" + methodName, e);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public void getTest() {
|
||||
System.out.println("dd");
|
||||
// return "test";
|
||||
}
|
||||
|
||||
public static void main(String args[]) {
|
||||
System.out.println(callStaticMethod(ReflectionUtils.class, "getTest"));
|
||||
System.out.println(callObjectMethod(new ReflectionUtils(), "getTest"));
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,6 +3,8 @@ package com.alibaba.druid.util;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import com.alibaba.druid.support.logging.Log;
|
||||
import com.alibaba.druid.support.logging.LogFactory;
|
||||
import com.alibaba.fastjson.JSON;
|
||||
|
||||
/**
|
||||
@@ -10,6 +12,8 @@ import com.alibaba.fastjson.JSON;
|
||||
*/
|
||||
public class StringUtils {
|
||||
|
||||
private final static Log LOG = LogFactory.getLog(StringUtils.class);
|
||||
|
||||
/**
|
||||
* Example: subString("12345","1","4")=23
|
||||
*
|
||||
@@ -52,6 +56,7 @@ public class StringUtils {
|
||||
try {
|
||||
return Integer.parseInt(in);
|
||||
} catch (NumberFormatException e) {
|
||||
LOG.warn("stringToInteger fail,string=" + in, e);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -67,6 +72,7 @@ public class StringUtils {
|
||||
try {
|
||||
return Long.parseLong(in);
|
||||
} catch (NumberFormatException e) {
|
||||
LOG.warn("stringToLong fail,string=" + in, e);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user