mirror of
https://github.com/alibaba/druid.git
synced 2023-03-04 19:17:16 +00:00
@@ -4,7 +4,7 @@
|
||||
|
||||
<groupId>com.alibaba</groupId>
|
||||
<artifactId>druid</artifactId>
|
||||
<version>0.2.19-SNAPSHOT</version>
|
||||
<version>0.2.19</version>
|
||||
|
||||
<packaging>jar</packaging>
|
||||
<name>druid</name>
|
||||
|
||||
@@ -19,7 +19,7 @@ public final class VERSION {
|
||||
|
||||
public final static int MajorVersion = 0;
|
||||
public final static int MinorVersion = 2;
|
||||
public final static int RevisionVersion = 18;
|
||||
public final static int RevisionVersion = 19;
|
||||
|
||||
public static String getVersionNumber() {
|
||||
return VERSION.MajorVersion + "." + VERSION.MinorVersion + "." + VERSION.RevisionVersion;
|
||||
|
||||
@@ -210,7 +210,7 @@ public abstract class DruidAbstractDataSource extends WrapperAdapter implements
|
||||
|
||||
private ObjectName objectName;
|
||||
|
||||
private final AtomicLong executeCount = new AtomicLong();
|
||||
protected final AtomicLong executeCount = new AtomicLong();
|
||||
|
||||
protected volatile Throwable createError;
|
||||
protected volatile Throwable lastError;
|
||||
@@ -231,7 +231,10 @@ public abstract class DruidAbstractDataSource extends WrapperAdapter implements
|
||||
|
||||
private Boolean useUnfairLock = null;
|
||||
|
||||
private boolean useLocalSessionState = true;
|
||||
private boolean useLocalSessionState = true;
|
||||
|
||||
protected long timeBetweenLogStatsMillis;
|
||||
protected DruidDataSourceStatLogger statLogger = new DruidDataSourceStatLoggerImpl();
|
||||
|
||||
public DruidAbstractDataSource(boolean lockFair){
|
||||
lock = new ReentrantLock(lockFair);
|
||||
@@ -239,15 +242,42 @@ public abstract class DruidAbstractDataSource extends WrapperAdapter implements
|
||||
notEmpty = lock.newCondition();
|
||||
empty = lock.newCondition();
|
||||
}
|
||||
|
||||
|
||||
public boolean isUseLocalSessionState() {
|
||||
return useLocalSessionState;
|
||||
}
|
||||
|
||||
|
||||
public void setUseLocalSessionState(boolean useLocalSessionState) {
|
||||
this.useLocalSessionState = useLocalSessionState;
|
||||
}
|
||||
|
||||
public DruidDataSourceStatLogger getStatLogger() {
|
||||
return statLogger;
|
||||
}
|
||||
|
||||
public void setStatLoggerClassName(String className) {
|
||||
Class<?> clazz;
|
||||
try {
|
||||
clazz = Class.forName(className);
|
||||
DruidDataSourceStatLogger statLogger = (DruidDataSourceStatLogger) clazz.newInstance();
|
||||
this.setStatLogger(statLogger);
|
||||
} catch (Exception e) {
|
||||
throw new IllegalArgumentException(className, e);
|
||||
}
|
||||
}
|
||||
|
||||
public void setStatLogger(DruidDataSourceStatLogger statLogger) {
|
||||
this.statLogger = statLogger;
|
||||
}
|
||||
|
||||
public long getTimeBetweenLogStatsMillis() {
|
||||
return timeBetweenLogStatsMillis;
|
||||
}
|
||||
|
||||
public void setTimeBetweenLogStatsMillis(long timeBetweenLogStatsMillis) {
|
||||
this.timeBetweenLogStatsMillis = timeBetweenLogStatsMillis;
|
||||
}
|
||||
|
||||
public boolean isOracle() {
|
||||
return isOracle;
|
||||
}
|
||||
|
||||
@@ -82,6 +82,7 @@ import com.alibaba.druid.util.JdbcUtils;
|
||||
import com.alibaba.druid.util.StringUtils;
|
||||
import com.alibaba.druid.wall.WallFilter;
|
||||
|
||||
;
|
||||
/**
|
||||
* @author ljw<ljw2083@alibaba-inc.com>
|
||||
* @author wenshao<szujobs@hotmail.com>
|
||||
@@ -119,6 +120,7 @@ public class DruidDataSource extends DruidAbstractDataSource implements DruidDat
|
||||
// threads
|
||||
private CreateConnectionThread createConnectionThread;
|
||||
private DestroyConnectionThread destoryConnectionThread;
|
||||
private LogStatsThread logStatsThread;
|
||||
|
||||
private final CountDownLatch initedLatch = new CountDownLatch(2);
|
||||
|
||||
@@ -131,7 +133,7 @@ public class DruidDataSource extends DruidAbstractDataSource implements DruidDat
|
||||
private volatile boolean closed = false;
|
||||
private long closeTimeMillis = -1L;
|
||||
|
||||
private JdbcDataSourceStat dataSourceStat;
|
||||
protected JdbcDataSourceStat dataSourceStat;
|
||||
|
||||
private boolean useGloalDataSourceStat = false;
|
||||
|
||||
@@ -175,14 +177,23 @@ public class DruidDataSource extends DruidAbstractDataSource implements DruidDat
|
||||
{
|
||||
String property = System.getProperty("druid.filters");
|
||||
|
||||
if (property == null || property.length() == 0) {
|
||||
return;
|
||||
if (property != null && property.length() > 0) {
|
||||
try {
|
||||
this.setFilters(property);
|
||||
} catch (SQLException e) {
|
||||
LOG.error("setFilters error", e);
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
this.setFilters(property);
|
||||
} catch (SQLException e) {
|
||||
LOG.error("setFilters error", e);
|
||||
}
|
||||
{
|
||||
String property = System.getProperty("druid.timeBetweenLogStatsMillis");
|
||||
if (property != null && property.length() > 0) {
|
||||
try {
|
||||
long value = Long.parseLong(property);
|
||||
this.setTimeBetweenLogStatsMillis(value);
|
||||
} catch (NumberFormatException e) {
|
||||
LOG.error("illegal property 'timeBetweenLogStatsMillis'", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -436,6 +447,10 @@ public class DruidDataSource extends DruidAbstractDataSource implements DruidDat
|
||||
+ maxActive);
|
||||
}
|
||||
|
||||
if (timeBetweenLogStatsMillis > 0 && useGloalDataSourceStat) {
|
||||
throw new IllegalArgumentException("timeBetweenLogStatsMillis not support useGloalDataSourceStat=true");
|
||||
}
|
||||
|
||||
if (this.driverClass != null) {
|
||||
this.driverClass = driverClass.trim();
|
||||
}
|
||||
@@ -492,7 +507,7 @@ public class DruidDataSource extends DruidAbstractDataSource implements DruidDat
|
||||
SQLException connectError = null;
|
||||
|
||||
try {
|
||||
// 初始化连接
|
||||
// init connections
|
||||
for (int i = 0, size = getInitialSize(); i < size; ++i) {
|
||||
Connection conn = createPhysicalConnection();
|
||||
DruidConnectionHolder holder = new DruidConnectionHolder(this, conn);
|
||||
@@ -508,6 +523,7 @@ public class DruidDataSource extends DruidAbstractDataSource implements DruidDat
|
||||
connectError = ex;
|
||||
}
|
||||
|
||||
createAndLogThread();
|
||||
createAndStartCreatorThread();
|
||||
createAndStartDestroyThread();
|
||||
|
||||
@@ -535,6 +551,16 @@ public class DruidDataSource extends DruidAbstractDataSource implements DruidDat
|
||||
}
|
||||
}
|
||||
|
||||
private void createAndLogThread() {
|
||||
if (this.timeBetweenLogStatsMillis <= 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
String threadName = "Druid-ConnectionPool-Log-" + System.identityHashCode(this);
|
||||
logStatsThread = new LogStatsThread(threadName);
|
||||
logStatsThread.start();
|
||||
}
|
||||
|
||||
private void createAndStartDestroyThread() {
|
||||
String threadName = "Druid-ConnectionPool-Destory-" + System.identityHashCode(this);
|
||||
destoryConnectionThread = new DestroyConnectionThread(threadName);
|
||||
@@ -1047,7 +1073,7 @@ public class DruidDataSource extends DruidAbstractDataSource implements DruidDat
|
||||
recycleErrorCount.incrementAndGet();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public long getRecycleErrorCount() {
|
||||
return recycleErrorCount.get();
|
||||
}
|
||||
@@ -1078,6 +1104,10 @@ public class DruidDataSource extends DruidAbstractDataSource implements DruidDat
|
||||
return;
|
||||
}
|
||||
|
||||
if (logStatsThread != null) {
|
||||
logStatsThread.interrupt();
|
||||
}
|
||||
|
||||
if (createConnectionThread != null) {
|
||||
createConnectionThread.interrupt();
|
||||
}
|
||||
@@ -1236,13 +1266,13 @@ public class DruidDataSource extends DruidAbstractDataSource implements DruidDat
|
||||
@Override
|
||||
public Connection getConnection(String username, String password) throws SQLException {
|
||||
if (!StringUtils.equals(username, this.username)) {
|
||||
throw new UnsupportedOperationException("Not supported by DruidDataSource");
|
||||
throw new UnsupportedOperationException("Not supported by DruidDataSource");
|
||||
}
|
||||
|
||||
|
||||
if (!StringUtils.equals(password, this.password)) {
|
||||
throw new UnsupportedOperationException("Not supported by DruidDataSource");
|
||||
throw new UnsupportedOperationException("Not supported by DruidDataSource");
|
||||
}
|
||||
|
||||
|
||||
return getConnection();
|
||||
}
|
||||
|
||||
@@ -1311,6 +1341,103 @@ public class DruidDataSource extends DruidAbstractDataSource implements DruidDat
|
||||
}
|
||||
}
|
||||
|
||||
public void logStats() {
|
||||
final DruidDataSourceStatLogger statLogger = this.statLogger;
|
||||
if (statLogger == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
DruidDataSourceStatValue statValue = getStatValueAndReset();
|
||||
|
||||
statLogger.log(statValue);
|
||||
}
|
||||
|
||||
public DruidDataSourceStatValue getStatValueAndReset() {
|
||||
DruidDataSourceStatValue value = new DruidDataSourceStatValue();
|
||||
|
||||
lock.lock();
|
||||
try {
|
||||
value.poolingCount = this.poolingCount;
|
||||
value.poolingPeak = this.poolingPeak;
|
||||
value.poolingPeakTime = this.poolingPeakTime;
|
||||
|
||||
value.activeCount = this.activeCount;
|
||||
value.activePeak = this.activePeak;
|
||||
value.activePeakTime = this.activePeakTime;
|
||||
|
||||
value.connectCount = this.connectCount;
|
||||
value.closeCount = this.closeCount;
|
||||
value.waitThreadCount = lock.getWaitQueueLength(notEmpty);
|
||||
value.notEmptyWaitCount = this.notEmptyWaitCount;
|
||||
value.notEmptyWaitNanos = this.notEmptyWaitNanos;
|
||||
|
||||
// reset
|
||||
this.poolingPeak = 0;
|
||||
this.poolingPeakTime = 0;
|
||||
this.activePeak = 0;
|
||||
this.activePeakTime = 0;
|
||||
this.connectCount = 0;
|
||||
this.closeCount = 0;
|
||||
|
||||
this.notEmptyWaitCount = 0;
|
||||
this.notEmptyWaitNanos = 0;
|
||||
} finally {
|
||||
lock.unlock();
|
||||
}
|
||||
|
||||
value.name = this.getName();
|
||||
value.dbType = this.getDbType();
|
||||
value.driverClassName = this.getDriverClassName();
|
||||
|
||||
value.url = this.getUrl();
|
||||
value.userName = this.getUsername();
|
||||
value.filterClassNames = this.getFilterClassNames();
|
||||
|
||||
value.initialSize = this.getInitialSize();
|
||||
value.minIdle = this.getMinIdle();
|
||||
value.maxActive = this.getMaxActive();
|
||||
|
||||
value.queryTimeout = this.getQueryTimeout();
|
||||
value.transactionQueryTimeout = this.getTransactionQueryTimeout();
|
||||
value.loginTimeout = this.getLoginTimeout();
|
||||
value.validConnectionCheckerClassName = this.getValidConnectionCheckerClassName();
|
||||
value.exceptionSorterClassName = this.getExceptionSorterClassName();
|
||||
|
||||
value.testOnBorrow = this.isTestOnBorrow();
|
||||
value.testOnReturn = this.isTestOnReturn();
|
||||
value.testWhileIdle = this.isTestWhileIdle();
|
||||
|
||||
value.defaultAutoCommit = this.isDefaultAutoCommit();
|
||||
value.defaultReadOnly = this.isDefaultAutoCommit();
|
||||
value.defaultTransactionIsolation = this.getDefaultTransactionIsolation();
|
||||
|
||||
value.logicConnectErrorCount = connectErrorCount.getAndSet(0);
|
||||
|
||||
value.physicalConnectCount = createCount.getAndSet(0);
|
||||
value.physicalCloseCount = destroyCount.getAndSet(0);
|
||||
value.physicalConnectErrorCount = createErrorCount.getAndSet(0);
|
||||
|
||||
value.executeCount = this.executeCount.getAndSet(0);
|
||||
value.errorCount = errorCount.getAndSet(0);
|
||||
value.commitCount = commitCount.getAndSet(0);
|
||||
value.rollbackCount = rollbackCount.getAndSet(0);
|
||||
|
||||
value.pstmtCacheHitCount = cachedPreparedStatementHitCount.getAndSet(0);
|
||||
value.pstmtCacheMissCount = cachedPreparedStatementMissCount.getAndSet(0);
|
||||
|
||||
value.startTransactionCount = startTransactionCount.getAndSet(0);
|
||||
value.transactionHistogram = this.getTransactionHistogram().toArrayAndReset();
|
||||
|
||||
value.connectionHoldTimeHistogram = this.getDataSourceStat().getConnectionHoldHistogram().toArrayAndReset();
|
||||
value.removeAbandoned = this.isRemoveAbandoned();
|
||||
value.clobOpenCount = this.getDataSourceStat().getClobOpenCountAndReset();
|
||||
value.blobOpenCount = this.getDataSourceStat().getBlobOpenCountAndReset();
|
||||
|
||||
value.sqlList = this.getDataSourceStat().getSqlStatMapAndReset();
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
public long getRemoveAbandonedCount() {
|
||||
return removeAbandonedCount;
|
||||
}
|
||||
@@ -1454,6 +1581,30 @@ public class DruidDataSource extends DruidAbstractDataSource implements DruidDat
|
||||
|
||||
}
|
||||
|
||||
public class LogStatsThread extends Thread {
|
||||
|
||||
public LogStatsThread(String name){
|
||||
super(name);
|
||||
this.setDaemon(true);
|
||||
}
|
||||
|
||||
public void run() {
|
||||
try {
|
||||
for (;;) {
|
||||
try {
|
||||
logStats();
|
||||
} catch (Exception e) {
|
||||
LOG.error("logStats error", e);
|
||||
}
|
||||
|
||||
Thread.sleep(timeBetweenLogStatsMillis);
|
||||
}
|
||||
} catch (InterruptedException e) {
|
||||
// skip
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public int removeAbandoned() {
|
||||
int removeCount = 0;
|
||||
|
||||
|
||||
@@ -72,4 +72,10 @@ public interface DruidDataSourceMBean extends DruidAbstractDataSourceMBean {
|
||||
void clearStatementCache() throws SQLException;
|
||||
|
||||
long getDiscardCount();
|
||||
|
||||
void setStatLoggerClassName(String className);
|
||||
|
||||
long getTimeBetweenLogStatsMillis();
|
||||
|
||||
void setTimeBetweenLogStatsMillis(long timeBetweenLogStatsMillis);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
/*
|
||||
* Copyright 1999-2011 Alibaba Group Holding Ltd.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.alibaba.druid.pool;
|
||||
|
||||
public interface DruidDataSourceStatLogger {
|
||||
|
||||
void log(DruidDataSourceStatValue statValue);
|
||||
}
|
||||
@@ -0,0 +1,168 @@
|
||||
/*
|
||||
* Copyright 1999-2011 Alibaba Group Holding Ltd.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.alibaba.druid.pool;
|
||||
|
||||
import static com.alibaba.druid.util.JdbcSqlStatUtils.rtrim;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import com.alibaba.druid.stat.JdbcSqlStatValue;
|
||||
import com.alibaba.druid.support.json.JSONUtils;
|
||||
import com.alibaba.druid.support.logging.Log;
|
||||
import com.alibaba.druid.support.logging.LogFactory;
|
||||
|
||||
public class DruidDataSourceStatLoggerImpl implements DruidDataSourceStatLogger {
|
||||
|
||||
private static Log LOG = LogFactory.getLog(DruidDataSourceStatLoggerImpl.class);
|
||||
|
||||
@Override
|
||||
public void log(DruidDataSourceStatValue statValue) {
|
||||
if (LOG.isInfoEnabled()) {
|
||||
Map<String, Object> map = new LinkedHashMap<String, Object>();
|
||||
|
||||
map.put("url", statValue.url);
|
||||
map.put("dbType", statValue.dbType);
|
||||
map.put("name", statValue.name);
|
||||
map.put("activeCount", statValue.activeCount);
|
||||
|
||||
if (statValue.activePeak > 0) {
|
||||
map.put("activePeak", statValue.activePeak);
|
||||
map.put("activePeakTime", statValue.getActivePeakTime());
|
||||
}
|
||||
map.put("poolingCount", statValue.poolingCount);
|
||||
if (statValue.poolingPeak > 0) {
|
||||
map.put("poolingPeak", statValue.poolingPeak);
|
||||
map.put("poolingPeakTime", statValue.getPoolingPeakTime());
|
||||
}
|
||||
map.put("connectCount", statValue.connectCount);
|
||||
map.put("closeCount", statValue.closeCount);
|
||||
|
||||
if (statValue.waitThreadCount > 0) {
|
||||
map.put("waitThreadCount", statValue.waitThreadCount);
|
||||
}
|
||||
if (statValue.notEmptyWaitCount > 0) {
|
||||
map.put("notEmptyWaitCount", statValue.notEmptyWaitCount);
|
||||
}
|
||||
if (statValue.getNotEmptyWaitMillis() > 0) {
|
||||
map.put("notEmptyWaitMillis", statValue.getNotEmptyWaitMillis());
|
||||
}
|
||||
if (statValue.logicConnectErrorCount > 0) {
|
||||
map.put("logicConnectErrorCount", statValue.logicConnectErrorCount);
|
||||
}
|
||||
if (statValue.physicalConnectCount > 0) {
|
||||
map.put("physicalConnectCount", statValue.physicalConnectCount);
|
||||
}
|
||||
if (statValue.physicalCloseCount > 0) {
|
||||
map.put("physicalCloseCount", statValue.physicalCloseCount);
|
||||
}
|
||||
if (statValue.physicalConnectErrorCount > 0) {
|
||||
map.put("physicalConnectErrorCount", statValue.physicalConnectErrorCount);
|
||||
}
|
||||
if (statValue.executeCount > 0) {
|
||||
map.put("executeCount", statValue.executeCount);
|
||||
}
|
||||
if (statValue.errorCount > 0) {
|
||||
map.put("errorCount", statValue.errorCount);
|
||||
}
|
||||
if (statValue.commitCount > 0) {
|
||||
map.put("commitCount", statValue.commitCount);
|
||||
}
|
||||
if (statValue.rollbackCount > 0) {
|
||||
map.put("rollbackCount", statValue.rollbackCount);
|
||||
}
|
||||
if (statValue.pstmtCacheHitCount > 0) {
|
||||
map.put("pstmtCacheHitCount", statValue.pstmtCacheHitCount);
|
||||
}
|
||||
if (statValue.pstmtCacheMissCount > 0) {
|
||||
map.put("pstmtCacheMissCount", statValue.pstmtCacheMissCount);
|
||||
}
|
||||
if (statValue.startTransactionCount > 0) {
|
||||
map.put("startTransactionCount", statValue.startTransactionCount);
|
||||
map.put("transactionHistogram", rtrim(statValue.transactionHistogram));
|
||||
}
|
||||
if (statValue.connectCount > 0) {
|
||||
map.put("connectionHoldTimeHistogram", rtrim(statValue.connectionHoldTimeHistogram));
|
||||
}
|
||||
if (statValue.clobOpenCount > 0) {
|
||||
map.put("clobOpenCount", statValue.clobOpenCount);
|
||||
}
|
||||
if (statValue.blobOpenCount > 0) {
|
||||
map.put("blobOpenCount", statValue.blobOpenCount);
|
||||
}
|
||||
|
||||
ArrayList<Map<String, Object>> sqlList = new ArrayList<Map<String, Object>>();
|
||||
if (statValue.sqlList.size() > 0) {
|
||||
for (JdbcSqlStatValue sqlStat : statValue.sqlList) {
|
||||
Map<String, Object> sqlStatMap = new LinkedHashMap<String, Object>();
|
||||
sqlStatMap.put("sql", sqlStat.sql);
|
||||
|
||||
if (sqlStat.getExecuteCount() > 0) {
|
||||
sqlStatMap.put("executeCount", sqlStat.getExecuteCount());
|
||||
sqlStatMap.put("executeMillisMax", sqlStat.getExecuteMillisMax());
|
||||
sqlStatMap.put("executeMillisTotal", sqlStat.getExecuteMillisTotal());
|
||||
|
||||
sqlStatMap.put("executeHistogram", rtrim(sqlStat.getExecuteHistogram()));
|
||||
sqlStatMap.put("executeAndResultHoldHistogram",
|
||||
rtrim(sqlStat.getExecuteAndResultHoldHistogram()));
|
||||
}
|
||||
|
||||
if (sqlStat.executeErrorCount > 0) {
|
||||
sqlStatMap.put("executeErrorCount", sqlStat.executeErrorCount);
|
||||
}
|
||||
if (sqlStat.runningCount > 0) {
|
||||
sqlStatMap.put("runningCount", sqlStat.runningCount);
|
||||
}
|
||||
sqlStatMap.put("concurrentMax", sqlStat.concurrentMax);
|
||||
|
||||
if (sqlStat.fetchRowCount > 0) {
|
||||
sqlStatMap.put("fetchRowCount", sqlStat.fetchRowCount);
|
||||
sqlStatMap.put("fetchRowCount", sqlStat.fetchRowCountMax);
|
||||
sqlStatMap.put("fetchRowHistogram", rtrim(sqlStat.getFetchRowHistogram()));
|
||||
}
|
||||
|
||||
if (sqlStat.updateCount > 0) {
|
||||
sqlStatMap.put("updateCount", sqlStat.updateCount);
|
||||
sqlStatMap.put("updateCountMax", sqlStat.updateCountMax);
|
||||
sqlStatMap.put("updateHistogram", rtrim(sqlStat.getUpdateHistogram()));
|
||||
}
|
||||
|
||||
if (sqlStat.inTransactionCount > 0) {
|
||||
sqlStatMap.put("inTransactionCount", sqlStat.inTransactionCount);
|
||||
}
|
||||
|
||||
if (sqlStat.clobOpenCount > 0) {
|
||||
sqlStatMap.put("clobOpenCount", sqlStat.clobOpenCount);
|
||||
}
|
||||
|
||||
if (sqlStat.blobOpenCount > 0) {
|
||||
sqlStatMap.put("blobOpenCount", sqlStat.blobOpenCount);
|
||||
}
|
||||
|
||||
sqlList.add(sqlStatMap);
|
||||
}
|
||||
|
||||
map.put("sqlList", sqlList);
|
||||
}
|
||||
|
||||
String text = JSONUtils.toJSONString(map);
|
||||
|
||||
LOG.info(text);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,100 @@
|
||||
/*
|
||||
* Copyright 1999-2011 Alibaba Group Holding Ltd.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.alibaba.druid.pool;
|
||||
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
import com.alibaba.druid.stat.JdbcSqlStatValue;
|
||||
|
||||
public class DruidDataSourceStatValue {
|
||||
|
||||
public String name;
|
||||
public String dbType;
|
||||
public String driverClassName;
|
||||
public String url;
|
||||
public String userName;
|
||||
public List<String> filterClassNames;
|
||||
public boolean removeAbandoned;
|
||||
|
||||
public int initialSize;
|
||||
public int minIdle;
|
||||
public int maxActive;
|
||||
public int queryTimeout;
|
||||
public int transactionQueryTimeout;
|
||||
public int loginTimeout;
|
||||
public String validConnectionCheckerClassName;
|
||||
public String exceptionSorterClassName;
|
||||
public boolean testOnBorrow;
|
||||
public boolean testOnReturn;
|
||||
public boolean testWhileIdle;
|
||||
public boolean defaultAutoCommit;
|
||||
public boolean defaultReadOnly;
|
||||
public Integer defaultTransactionIsolation;
|
||||
|
||||
public int activeCount;
|
||||
public int activePeak;
|
||||
public long activePeakTime;
|
||||
|
||||
public int poolingCount;
|
||||
public int poolingPeak;
|
||||
public long poolingPeakTime;
|
||||
|
||||
public long connectCount;
|
||||
public long closeCount;
|
||||
public long waitThreadCount;
|
||||
public long notEmptyWaitCount;
|
||||
public long notEmptyWaitNanos;
|
||||
|
||||
public long logicConnectErrorCount;
|
||||
public long physicalConnectCount;
|
||||
public long physicalCloseCount;
|
||||
public long physicalConnectErrorCount;
|
||||
public long executeCount;
|
||||
public long errorCount;
|
||||
public long commitCount;
|
||||
public long rollbackCount;
|
||||
public long pstmtCacheHitCount;
|
||||
public long pstmtCacheMissCount;
|
||||
public long startTransactionCount;
|
||||
public long[] transactionHistogram;
|
||||
public long[] connectionHoldTimeHistogram;
|
||||
|
||||
public long clobOpenCount;
|
||||
public long blobOpenCount;
|
||||
|
||||
public List<JdbcSqlStatValue> sqlList;
|
||||
|
||||
public Date getPoolingPeakTime() {
|
||||
if (poolingPeakTime <= 0) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return new Date(poolingPeakTime);
|
||||
}
|
||||
|
||||
public Date getActivePeakTime() {
|
||||
if (activePeakTime <= 0) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return new Date(activePeakTime);
|
||||
}
|
||||
|
||||
public long getNotEmptyWaitMillis() {
|
||||
return notEmptyWaitNanos / (1000 * 1000);
|
||||
}
|
||||
}
|
||||
@@ -15,9 +15,10 @@
|
||||
*/
|
||||
package com.alibaba.druid.stat;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Iterator;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Properties;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
@@ -257,7 +258,7 @@ public class JdbcDataSourceStat implements JdbcDataSourceStatMBean {
|
||||
}
|
||||
|
||||
public Map<String, JdbcSqlStat> getSqlStatMap() {
|
||||
Map<String, JdbcSqlStat> map = new HashMap<String, JdbcSqlStat>();
|
||||
Map<String, JdbcSqlStat> map = new LinkedHashMap<String, JdbcSqlStat>(sqlStatMap.size());
|
||||
lock.readLock().lock();
|
||||
try {
|
||||
map.putAll(sqlStatMap);
|
||||
@@ -266,6 +267,34 @@ public class JdbcDataSourceStat implements JdbcDataSourceStatMBean {
|
||||
}
|
||||
return map;
|
||||
}
|
||||
|
||||
public List<JdbcSqlStatValue> getSqlStatMapAndReset() {
|
||||
List<JdbcSqlStat> stats = new ArrayList<JdbcSqlStat>(sqlStatMap.size());
|
||||
lock.writeLock().lock();
|
||||
try {
|
||||
Iterator<Map.Entry<String, JdbcSqlStat>> iter = sqlStatMap.entrySet().iterator();
|
||||
while (iter.hasNext()) {
|
||||
Map.Entry<String, JdbcSqlStat> entry = iter.next();
|
||||
JdbcSqlStat stat = entry.getValue();
|
||||
if (stat.getExecuteCount() == 0 && stat.getRunningCount() == 0) {
|
||||
stat.setRemoved(true);
|
||||
iter.remove();
|
||||
} else {
|
||||
stats.add(entry.getValue());
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
lock.writeLock().unlock();
|
||||
}
|
||||
|
||||
List<JdbcSqlStatValue> values = new ArrayList<JdbcSqlStatValue>(stats.size());
|
||||
for (int i = 0; i < stats.size(); ++i) {
|
||||
JdbcSqlStat stat = stats.get(i);
|
||||
JdbcSqlStatValue value = stat.getValueAndReset();
|
||||
values.add(value);
|
||||
}
|
||||
return values;
|
||||
}
|
||||
|
||||
public JdbcSqlStat getSqlStat(String sql) {
|
||||
lock.readLock().lock();
|
||||
@@ -346,6 +375,10 @@ public class JdbcDataSourceStat implements JdbcDataSourceStatMBean {
|
||||
public long getClobOpenCount() {
|
||||
return clobOpenCount.get();
|
||||
}
|
||||
|
||||
public long getClobOpenCountAndReset() {
|
||||
return clobOpenCount.getAndSet(0);
|
||||
}
|
||||
|
||||
public void incrementClobOpenCount() {
|
||||
clobOpenCount.incrementAndGet();
|
||||
@@ -354,6 +387,10 @@ public class JdbcDataSourceStat implements JdbcDataSourceStatMBean {
|
||||
public long getBlobOpenCount() {
|
||||
return blobOpenCount.get();
|
||||
}
|
||||
|
||||
public long getBlobOpenCountAndReset() {
|
||||
return blobOpenCount.getAndSet(0);
|
||||
}
|
||||
|
||||
public void incrementBlobOpenCount() {
|
||||
blobOpenCount.incrementAndGet();
|
||||
|
||||
@@ -323,7 +323,6 @@ public final class JdbcSqlStat implements JdbcSqlStatMBean {
|
||||
executeSpanNanoTotalUpdater.set(this, 0);
|
||||
executeSpanNanoMaxUpdater.set(this, 0);
|
||||
executeNanoSpanMaxOccurTime = 0;
|
||||
runningCountUpdater.set(this, 0);
|
||||
concurrentMaxUpdater.set(this, 0);
|
||||
|
||||
executeErrorCountUpdater.set(this, 0);
|
||||
@@ -380,6 +379,88 @@ public final class JdbcSqlStat implements JdbcSqlStatMBean {
|
||||
readerOpenCountUpdater.set(this, 0);
|
||||
}
|
||||
|
||||
public JdbcSqlStatValue getValueAndReset() {
|
||||
JdbcSqlStatValue val = new JdbcSqlStatValue();
|
||||
|
||||
val.sql = sql;
|
||||
val.executeLastStartTime = executeLastStartTime;
|
||||
executeLastStartTime = 0;
|
||||
|
||||
val.executeBatchSizeTotal = executeBatchSizeTotalUpdater.getAndSet(this, 0);
|
||||
val.executeBatchSizeMax = executeBatchSizeMaxUpdater.getAndSet(this, 0);
|
||||
|
||||
val.executeSuccessCount = executeSuccessCountUpdater.getAndSet(this, 0);
|
||||
val.executeSpanNanoTotal = executeSpanNanoTotalUpdater.getAndSet(this, 0);
|
||||
val.executeSpanNanoMax = executeSpanNanoMaxUpdater.getAndSet(this, 0);
|
||||
val.executeNanoSpanMaxOccurTime = executeNanoSpanMaxOccurTime;
|
||||
executeNanoSpanMaxOccurTime = 0;
|
||||
|
||||
val.runningCount = this.runningCount;
|
||||
|
||||
val.concurrentMax = concurrentMaxUpdater.getAndSet(this, 0);
|
||||
|
||||
val.executeErrorCount = executeErrorCountUpdater.getAndSet(this, 0);
|
||||
|
||||
val.executeErrorLast = executeErrorLast;
|
||||
executeErrorLast = null;
|
||||
|
||||
val.executeErrorLastTime = executeErrorLastTime;
|
||||
executeErrorLastTime = 0;
|
||||
|
||||
val.updateCount = updateCountUpdater.getAndSet(this, 0);
|
||||
val.updateCountMax = updateCountMaxUpdater.getAndSet(this, 0);
|
||||
val.fetchRowCount = fetchRowCountUpdater.getAndSet(this, 0);
|
||||
val.fetchRowCountMax = fetchRowCountMaxUpdater.getAndSet(this, 0);
|
||||
|
||||
val.histogram_0_1 = histogram_0_1_Updater.getAndSet(this, 0);
|
||||
val.histogram_1_10 = histogram_1_10_Updater.getAndSet(this, 0);
|
||||
val.histogram_10_100 = histogram_10_100_Updater.getAndSet(this, 0);
|
||||
val.histogram_100_1000 = histogram_100_1000_Updater.getAndSet(this, 0);
|
||||
val.histogram_1000_10000 = histogram_1000_10000_Updater.getAndSet(this, 0);
|
||||
val.histogram_10000_100000 = histogram_10000_100000_Updater.getAndSet(this, 0);
|
||||
val.histogram_100000_1000000 = histogram_100000_1000000_Updater.getAndSet(this, 0);
|
||||
val.histogram_1000000_more = histogram_1000000_more_Updater.getAndSet(this, 0);
|
||||
|
||||
val.lastSlowParameters = lastSlowParameters;
|
||||
lastSlowParameters = null;
|
||||
|
||||
val.inTransactionCount = inTransactionCountUpdater.getAndSet(this, 0);
|
||||
val.resultSetHoldTimeNano = resultSetHoldTimeNanoUpdater.getAndSet(this, 0);
|
||||
val.executeAndResultSetHoldTime = executeAndResultSetHoldTimeUpdater.getAndSet(this, 0);
|
||||
|
||||
val.fetchRowCount_0_1 = fetchRowCount_0_1_Updater.getAndSet(this, 0);
|
||||
val.fetchRowCount_1_10 = fetchRowCount_1_10_Updater.getAndSet(this, 0);
|
||||
val.fetchRowCount_10_100 = fetchRowCount_10_100_Updater.getAndSet(this, 0);
|
||||
val.fetchRowCount_100_1000 = fetchRowCount_100_1000_Updater.getAndSet(this, 0);
|
||||
val.fetchRowCount_1000_10000 = fetchRowCount_1000_10000_Updater.getAndSet(this, 0);
|
||||
val.fetchRowCount_10000_more = fetchRowCount_10000_more_Updater.getAndSet(this, 0);
|
||||
|
||||
val.updateCount_0_1 = updateCount_0_1_Updater.getAndSet(this, 0);
|
||||
val.updateCount_1_10 = updateCount_1_10_Updater.getAndSet(this, 0);
|
||||
val.updateCount_10_100 = updateCount_10_100_Updater.getAndSet(this, 0);
|
||||
val.updateCount_100_1000 = updateCount_100_1000_Updater.getAndSet(this, 0);
|
||||
val.updateCount_1000_10000 = updateCount_1000_10000_Updater.getAndSet(this, 0);
|
||||
val.updateCount_10000_more = updateCount_10000_more_Updater.getAndSet(this, 0);
|
||||
|
||||
val.executeAndResultHoldTime_0_1 = executeAndResultHoldTime_0_1_Updater.getAndSet(this, 0);
|
||||
val.executeAndResultHoldTime_1_10 = executeAndResultHoldTime_1_10_Updater.getAndSet(this, 0);
|
||||
val.executeAndResultHoldTime_10_100 = executeAndResultHoldTime_10_100_Updater.getAndSet(this, 0);
|
||||
val.executeAndResultHoldTime_100_1000 = executeAndResultHoldTime_100_1000_Updater.getAndSet(this, 0);
|
||||
val.executeAndResultHoldTime_1000_10000 = executeAndResultHoldTime_1000_10000_Updater.getAndSet(this, 0);
|
||||
val.executeAndResultHoldTime_10000_100000 = executeAndResultHoldTime_10000_100000_Updater.getAndSet(this, 0);
|
||||
val.executeAndResultHoldTime_100000_1000000 = executeAndResultHoldTime_100000_1000000_Updater.getAndSet(this, 0);
|
||||
val.executeAndResultHoldTime_1000000_more = executeAndResultHoldTime_1000000_more_Updater.getAndSet(this, 0);
|
||||
|
||||
val.blobOpenCount = blobOpenCountUpdater.getAndSet(this, 0);
|
||||
val.clobOpenCount = clobOpenCountUpdater.getAndSet(this, 0);
|
||||
val.readStringLength = readStringLengthUpdater.getAndSet(this, 0);
|
||||
val.readBytesLength = readBytesLengthUpdater.getAndSet(this, 0);
|
||||
val.inputStreamOpenCount = inputStreamOpenCountUpdater.getAndSet(this, 0);
|
||||
val.readerOpenCount = readerOpenCountUpdater.getAndSet(this, 0);
|
||||
|
||||
return val;
|
||||
}
|
||||
|
||||
public long getConcurrentMax() {
|
||||
return concurrentMax;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,150 @@
|
||||
/*
|
||||
* Copyright 1999-2011 Alibaba Group Holding Ltd.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.alibaba.druid.stat;
|
||||
|
||||
public class JdbcSqlStatValue {
|
||||
|
||||
public String sql;
|
||||
public long id;
|
||||
public String dataSource;
|
||||
public long executeLastStartTime;
|
||||
|
||||
public long executeBatchSizeTotal;
|
||||
public int executeBatchSizeMax;
|
||||
|
||||
public long executeSuccessCount;
|
||||
public long executeSpanNanoTotal;
|
||||
public long executeSpanNanoMax;
|
||||
public int runningCount;
|
||||
public int concurrentMax;
|
||||
public long resultSetHoldTimeNano;
|
||||
public long executeAndResultSetHoldTime;
|
||||
|
||||
public String name;
|
||||
public String file;
|
||||
public String dbType;
|
||||
|
||||
public long executeNanoSpanMaxOccurTime;
|
||||
|
||||
public long executeErrorCount;
|
||||
public Throwable executeErrorLast;
|
||||
public long executeErrorLastTime;
|
||||
|
||||
public long updateCount;
|
||||
public long updateCountMax;
|
||||
public long fetchRowCount;
|
||||
public long fetchRowCountMax;
|
||||
|
||||
public long inTransactionCount;
|
||||
|
||||
public String lastSlowParameters;
|
||||
|
||||
public long clobOpenCount;
|
||||
public long blobOpenCount;
|
||||
public long readStringLength;
|
||||
public long readBytesLength;
|
||||
|
||||
public long inputStreamOpenCount;
|
||||
public long readerOpenCount;
|
||||
|
||||
public long histogram_0_1;
|
||||
public long histogram_1_10;
|
||||
public int histogram_10_100;
|
||||
public int histogram_100_1000;
|
||||
public int histogram_1000_10000;
|
||||
public int histogram_10000_100000;
|
||||
public int histogram_100000_1000000;
|
||||
public int histogram_1000000_more;
|
||||
|
||||
public long[] getExecuteHistogram() {
|
||||
return new long[] { histogram_0_1, //
|
||||
histogram_1_10, //
|
||||
histogram_10_100, //
|
||||
histogram_100_1000, //
|
||||
histogram_1000_10000, //
|
||||
histogram_10000_100000, //
|
||||
histogram_100000_1000000, //
|
||||
histogram_1000000_more, //
|
||||
};
|
||||
}
|
||||
|
||||
public long executeAndResultHoldTime_0_1;
|
||||
public long executeAndResultHoldTime_1_10;
|
||||
public int executeAndResultHoldTime_10_100;
|
||||
public int executeAndResultHoldTime_100_1000;
|
||||
public int executeAndResultHoldTime_1000_10000;
|
||||
public int executeAndResultHoldTime_10000_100000;
|
||||
public int executeAndResultHoldTime_100000_1000000;
|
||||
public int executeAndResultHoldTime_1000000_more;
|
||||
|
||||
public long[] getExecuteAndResultHoldHistogram() {
|
||||
return new long[] { executeAndResultHoldTime_0_1, //
|
||||
executeAndResultHoldTime_1_10, //
|
||||
executeAndResultHoldTime_10_100, //
|
||||
executeAndResultHoldTime_100_1000, //
|
||||
executeAndResultHoldTime_1000_10000, //
|
||||
executeAndResultHoldTime_10000_100000, //
|
||||
executeAndResultHoldTime_100000_1000000, //
|
||||
executeAndResultHoldTime_1000000_more, //
|
||||
};
|
||||
}
|
||||
|
||||
public long fetchRowCount_0_1;
|
||||
public long fetchRowCount_1_10;
|
||||
public long fetchRowCount_10_100;
|
||||
public int fetchRowCount_100_1000;
|
||||
public int fetchRowCount_1000_10000;
|
||||
public int fetchRowCount_10000_more;
|
||||
|
||||
public long[] getFetchRowHistogram() {
|
||||
return new long[] { fetchRowCount_0_1, //
|
||||
fetchRowCount_1_10, //
|
||||
fetchRowCount_10_100, //
|
||||
fetchRowCount_100_1000, //
|
||||
fetchRowCount_1000_10000, //
|
||||
fetchRowCount_10000_more, //
|
||||
};
|
||||
}
|
||||
|
||||
public long updateCount_0_1;
|
||||
public long updateCount_1_10;
|
||||
public long updateCount_10_100;
|
||||
public int updateCount_100_1000;
|
||||
public int updateCount_1000_10000;
|
||||
public int updateCount_10000_more;
|
||||
|
||||
public long[] getUpdateHistogram() {
|
||||
return new long[] { updateCount_0_1, //
|
||||
updateCount_1_10, //
|
||||
updateCount_10_100, //
|
||||
updateCount_100_1000, //
|
||||
updateCount_1000_10000, //
|
||||
updateCount_10000_more, //
|
||||
};
|
||||
}
|
||||
|
||||
public long getExecuteCount() {
|
||||
return executeErrorCount + executeSuccessCount;
|
||||
}
|
||||
|
||||
public long getExecuteMillisMax() {
|
||||
return executeSpanNanoMax / (1000 * 1000);
|
||||
}
|
||||
|
||||
public long getExecuteMillisTotal() {
|
||||
return executeSpanNanoTotal / (1000 * 1000);
|
||||
}
|
||||
}
|
||||
@@ -66,6 +66,7 @@ public class SLF4JImpl implements Log {
|
||||
@Override
|
||||
public void info(String msg) {
|
||||
infoCount++;
|
||||
log.log(null, callerFQCN, LocationAwareLogger.INFO_INT, msg, null, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -77,6 +77,15 @@ public class Histogram {
|
||||
return array;
|
||||
}
|
||||
|
||||
public long[] toArrayAndReset() {
|
||||
long[] array = new long[rangeCounters.length()];
|
||||
for (int i = 0; i < rangeCounters.length(); i++) {
|
||||
array[i] = rangeCounters.getAndSet(i, 0);
|
||||
}
|
||||
|
||||
return array;
|
||||
}
|
||||
|
||||
public long[] getRanges() {
|
||||
return ranges;
|
||||
}
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
package com.alibaba.druid.util;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.Arrays;
|
||||
import java.util.Map;
|
||||
|
||||
import com.alibaba.druid.stat.JdbcSqlStat;
|
||||
@@ -41,4 +42,19 @@ public class JdbcSqlStatUtils {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public static long[] rtrim(long[] array) {
|
||||
int notZeroLen = array.length;
|
||||
for (int i = array.length - 1; i >= 0; --i, notZeroLen--) {
|
||||
if (array[i] != 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (notZeroLen != array.length) {
|
||||
array = Arrays.copyOf(array, notZeroLen);
|
||||
}
|
||||
|
||||
return array;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,9 +5,10 @@ import java.sql.PreparedStatement;
|
||||
import java.sql.ResultSet;
|
||||
import java.util.Iterator;
|
||||
|
||||
import junit.framework.Assert;
|
||||
import junit.framework.TestCase;
|
||||
|
||||
import org.junit.Assert;
|
||||
|
||||
import com.alibaba.druid.pool.DruidDataSource;
|
||||
import com.alibaba.druid.stat.DruidDataSourceStatManager;
|
||||
import com.alibaba.druid.stat.JdbcSqlStat;
|
||||
@@ -24,6 +25,7 @@ public class TestOnBorrowFileAndNameTest extends TestCase {
|
||||
dataSource.setName("com.alibaba.dragoon.monitor");
|
||||
dataSource.setMinIdle(0);
|
||||
dataSource.setPoolPreparedStatements(false);
|
||||
dataSource.setTestOnBorrow(true);
|
||||
dataSource.setValidationQuery("SELECT 1");
|
||||
dataSource.setFilters("stat");
|
||||
|
||||
|
||||
@@ -0,0 +1,30 @@
|
||||
package com.alibaba.druid.bvt.pool;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
import org.junit.Assert;
|
||||
|
||||
import com.alibaba.druid.pool.DruidDataSource;
|
||||
import com.alibaba.druid.util.JdbcUtils;
|
||||
|
||||
public class TimeBetweenLogStatsMillisTest extends TestCase {
|
||||
|
||||
private DruidDataSource dataSource;
|
||||
|
||||
protected void setUp() throws Exception {
|
||||
dataSource = new DruidDataSource();
|
||||
|
||||
dataSource.setUrl("jdbc:mock:xxx");
|
||||
dataSource.setTimeBetweenLogStatsMillis(1000);
|
||||
// dataSource.setFilters("log4j");
|
||||
}
|
||||
|
||||
protected void tearDown() throws Exception {
|
||||
JdbcUtils.close(dataSource);
|
||||
}
|
||||
|
||||
public void test_0() throws Exception {
|
||||
dataSource.init();
|
||||
Assert.assertEquals(1000, dataSource.getTimeBetweenLogStatsMillis());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
package com.alibaba.druid.bvt.pool;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
import org.junit.Assert;
|
||||
|
||||
import com.alibaba.druid.pool.DruidDataSource;
|
||||
import com.alibaba.druid.util.JdbcUtils;
|
||||
|
||||
public class TimeBetweenLogStatsMillisTest2 extends TestCase {
|
||||
|
||||
private DruidDataSource dataSource;
|
||||
|
||||
protected void setUp() throws Exception {
|
||||
System.setProperty("druid.timeBetweenLogStatsMillis", "1000");
|
||||
|
||||
dataSource = new DruidDataSource();
|
||||
dataSource.setUrl("jdbc:mock:xxx");
|
||||
}
|
||||
|
||||
protected void tearDown() throws Exception {
|
||||
JdbcUtils.close(dataSource);
|
||||
System.clearProperty("druid.timeBetweenLogStatsMillis");
|
||||
}
|
||||
|
||||
public void test_0() throws Exception {
|
||||
dataSource.init();
|
||||
Assert.assertEquals(1000, dataSource.getTimeBetweenLogStatsMillis());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
package com.alibaba.druid.bvt.pool;
|
||||
|
||||
import java.sql.Connection;
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.ResultSet;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
import org.junit.Assert;
|
||||
|
||||
import com.alibaba.druid.pool.DruidDataSource;
|
||||
import com.alibaba.druid.util.JdbcUtils;
|
||||
|
||||
public class TimeBetweenLogStatsMillisTest3 extends TestCase {
|
||||
|
||||
private DruidDataSource dataSource;
|
||||
|
||||
protected void setUp() throws Exception {
|
||||
System.setProperty("druid.timeBetweenLogStatsMillis", "10");
|
||||
|
||||
dataSource = new DruidDataSource();
|
||||
dataSource.setUrl("jdbc:mock:xxx");
|
||||
dataSource.setFilters("stat");
|
||||
}
|
||||
|
||||
protected void tearDown() throws Exception {
|
||||
JdbcUtils.close(dataSource);
|
||||
System.clearProperty("druid.timeBetweenLogStatsMillis");
|
||||
}
|
||||
|
||||
public void test_0() throws Exception {
|
||||
dataSource.init();
|
||||
for (int i = 0; i < 10; ++i) {
|
||||
Connection conn = dataSource.getConnection();
|
||||
PreparedStatement stmt = conn.prepareStatement("select ?");
|
||||
stmt.setString(1, "aaa");
|
||||
ResultSet rs = stmt.executeQuery();
|
||||
rs.close();
|
||||
stmt.close();
|
||||
conn.close();
|
||||
|
||||
Thread.sleep(10);
|
||||
}
|
||||
Assert.assertEquals(10, dataSource.getTimeBetweenLogStatsMillis());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,78 @@
|
||||
/*
|
||||
* Copyright 1999-2011 Alibaba Group Holding Ltd.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.alibaba.druid.bvt.proxy.filter;
|
||||
|
||||
import java.sql.Connection;
|
||||
import java.sql.Statement;
|
||||
import java.util.Set;
|
||||
|
||||
import javax.management.openmbean.TabularData;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
import org.junit.Assert;
|
||||
|
||||
import com.alibaba.druid.pool.DruidDataSource;
|
||||
import com.alibaba.druid.stat.DruidDataSourceStatManager;
|
||||
import com.alibaba.druid.stat.JdbcStatManager;
|
||||
import com.alibaba.druid.support.json.JSONUtils;
|
||||
import com.alibaba.druid.util.JdbcUtils;
|
||||
|
||||
public class MergeStatFilterTest_tddl_2 extends TestCase {
|
||||
|
||||
private DruidDataSource dataSource;
|
||||
|
||||
protected void setUp() throws Exception {
|
||||
TabularData sqlList = JdbcStatManager.getInstance().getSqlList();
|
||||
if (sqlList.size() > 0) {
|
||||
for (Object item : JdbcStatManager.getInstance().getSqlList().values()) {
|
||||
String text = JSONUtils.toJSONString(item);
|
||||
System.out.println(text);
|
||||
}
|
||||
}
|
||||
|
||||
Assert.assertEquals(0, JdbcStatManager.getInstance().getSqlList().size());
|
||||
|
||||
dataSource = new DruidDataSource();
|
||||
dataSource.setUrl("jdbc:mock:xx");
|
||||
dataSource.setFilters("mergeStat");
|
||||
dataSource.setDbType("mysql");
|
||||
}
|
||||
|
||||
protected void tearDown() throws Exception {
|
||||
JdbcUtils.close(dataSource);
|
||||
|
||||
Assert.assertEquals(0, JdbcStatManager.getInstance().getSqlList().size());
|
||||
}
|
||||
|
||||
public void test_merge() throws Exception {
|
||||
for (int i = 1000; i < 2000; ++i) {
|
||||
String tableName = "t" + i;
|
||||
String sql = "insert into " + tableName + " (fid, fname) values (?, ?)";
|
||||
Connection conn = dataSource.getConnection();
|
||||
|
||||
Statement stmt = conn.createStatement();
|
||||
stmt.execute(sql);
|
||||
stmt.close();
|
||||
|
||||
conn.close();
|
||||
}
|
||||
|
||||
Assert.assertEquals(1, dataSource.getDataSourceStat().getSqlStatMap().size());
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user