Merge remote-tracking branch 'zhb/master'

Conflicts:
	src/main/java/com/alibaba/druid/support/http/StatViewServlet.java
This commit is contained in:
zhouhaibin
2012-08-10 12:45:48 +08:00
parent e5365eae94
commit 339e5f944f
20 changed files with 611 additions and 301 deletions
@@ -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;
}
}