diff --git a/src/main/java/com/alibaba/druid/pool/DruidDataSource.java b/src/main/java/com/alibaba/druid/pool/DruidDataSource.java index c10d4c0ea5..1db4b9488d 100644 --- a/src/main/java/com/alibaba/druid/pool/DruidDataSource.java +++ b/src/main/java/com/alibaba/druid/pool/DruidDataSource.java @@ -82,6 +82,7 @@ import com.alibaba.druid.util.JdbcUtils; import com.alibaba.druid.util.StringUtils; import com.alibaba.druid.wall.WallFilter; +; /** * @author ljw * @author wenshao @@ -176,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); + } } } } @@ -1336,9 +1346,9 @@ public class DruidDataSource extends DruidAbstractDataSource implements DruidDat if (statLogger == null) { return; } - + DruidDataSourceStatValue statValue = getStatValueAndReset(); - + statLogger.log(statValue); } diff --git a/src/main/java/com/alibaba/druid/pool/DruidDataSourceStatLoggerImpl.java b/src/main/java/com/alibaba/druid/pool/DruidDataSourceStatLoggerImpl.java index 0de10684f0..f60a6417bc 100644 --- a/src/main/java/com/alibaba/druid/pool/DruidDataSourceStatLoggerImpl.java +++ b/src/main/java/com/alibaba/druid/pool/DruidDataSourceStatLoggerImpl.java @@ -15,6 +15,8 @@ */ 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; @@ -37,24 +39,43 @@ public class DruidDataSourceStatLoggerImpl implements DruidDataSourceStatLogger map.put("dbType", statValue.dbType); map.put("name", statValue.name); map.put("activeCount", statValue.activeCount); - map.put("activePeak", statValue.activePeak); - map.put("activePeakTime", statValue.getActivePeakTime()); + if (statValue.activePeak > 0) { + map.put("activePeak", statValue.activePeak); + map.put("activePeakTime", statValue.getActivePeakTime()); + } map.put("poolingCount", statValue.poolingCount); - map.put("poolingPeak", statValue.poolingPeak); - map.put("poolingPeakTime", statValue.getPoolingPeakTime()); + if (statValue.poolingPeak > 0) { + map.put("poolingPeak", statValue.poolingPeak); + map.put("poolingPeakTime", statValue.getPoolingPeakTime()); + } map.put("connectCount", statValue.connectCount); - map.put("closeCount", statValue.closeCount); - map.put("waitThreadCount", statValue.waitThreadCount); - map.put("notEmptyWaitCount", statValue.notEmptyWaitCount); - map.put("notEmptyWaitMillis", statValue.getNotEmptyWaitMillis()); - map.put("logicConnectErrorCount", statValue.logicConnectErrorCount); - map.put("physicalConnectCount", statValue.physicalConnectCount); - map.put("physicalCloseCount", statValue.physicalCloseCount); - map.put("physicalConnectErrorCount", statValue.physicalConnectErrorCount); - map.put("executeCount", statValue.executeCount); + 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); } @@ -64,13 +85,19 @@ public class DruidDataSourceStatLoggerImpl implements DruidDataSourceStatLogger if (statValue.rollbackCount > 0) { map.put("rollbackCount", statValue.rollbackCount); } - map.put("pstmtCacheHitCount", statValue.pstmtCacheHitCount); - map.put("pstmtCacheMissCount", statValue.pstmtCacheMissCount); + 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", statValue.transactionHistogram); + map.put("transactionHistogram", rtrim(statValue.transactionHistogram)); + } + if (statValue.connectCount > 0) { + map.put("connectionHoldTimeHistogram", rtrim(statValue.connectionHoldTimeHistogram)); } - map.put("connectionHoldTimeHistogram", statValue.connectionHoldTimeHistogram); if (statValue.clobOpenCount > 0) { map.put("clobOpenCount", statValue.clobOpenCount); } @@ -79,47 +106,57 @@ public class DruidDataSourceStatLoggerImpl implements DruidDataSourceStatLogger } ArrayList> sqlList = new ArrayList>(); - for (JdbcSqlStatValue sqlStat : statValue.sqlList) { - Map sqlStatMap = new LinkedHashMap(); - sqlStatMap.put("sql", sqlStat.sql); - sqlStatMap.put("executeCount", sqlStat.getExecuteCount()); - if (sqlStat.executeErrorCount > 0) { - sqlStatMap.put("executeErrorCount", sqlStat.executeErrorCount); - } - if (sqlStat.runningCount > 0) { - sqlStatMap.put("runningCount", sqlStat.runningCount); - } - sqlStatMap.put("concurrentMax", sqlStat.concurrentMax); + if (statValue.sqlList.size() > 0) { + for (JdbcSqlStatValue sqlStat : statValue.sqlList) { + Map sqlStatMap = new LinkedHashMap(); + sqlStatMap.put("sql", sqlStat.sql); - sqlStatMap.put("executeMillisMax", sqlStat.getExecuteMillisMax()); - sqlStatMap.put("executeMillisTotal", sqlStat.getExecuteMillisTotal()); + if (sqlStat.getExecuteCount() > 0) { + sqlStatMap.put("executeCount", sqlStat.getExecuteCount()); + sqlStatMap.put("executeMillisMax", sqlStat.getExecuteMillisMax()); + sqlStatMap.put("executeMillisTotal", sqlStat.getExecuteMillisTotal()); - sqlStatMap.put("executeHistogram", sqlStat.getExecuteHistogram()); - sqlStatMap.put("executeAndResultHoldHistogram", sqlStat.getExecuteAndResultHoldHistogram()); - if (sqlStat.fetchRowCount > 0) { - sqlStatMap.put("fetchRowCount", sqlStat.fetchRowCount); - sqlStatMap.put("fetchRowCount", sqlStat.fetchRowCountMax); - sqlStatMap.put("fetchRowHistogram", sqlStat.getFetchRowHistogram()); - } + sqlStatMap.put("executeHistogram", rtrim(sqlStat.getExecuteHistogram())); + sqlStatMap.put("executeAndResultHoldHistogram", + rtrim(sqlStat.getExecuteAndResultHoldHistogram())); + } - if (sqlStat.updateCount > 0) { - sqlStatMap.put("updateCount", sqlStat.updateCount); - sqlStatMap.put("updateCountMax", sqlStat.updateCountMax); - sqlStatMap.put("updateHistogram", sqlStat.getUpdateHistogram()); - } + 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.inTransactionCount > 0) { - sqlStatMap.put("inTransactionCount", sqlStat.inTransactionCount); - } + if (sqlStat.fetchRowCount > 0) { + sqlStatMap.put("fetchRowCount", sqlStat.fetchRowCount); + sqlStatMap.put("fetchRowCount", sqlStat.fetchRowCountMax); + sqlStatMap.put("fetchRowHistogram", rtrim(sqlStat.getFetchRowHistogram())); + } - if (sqlStat.clobOpenCount > 0) { - sqlStatMap.put("clobOpenCount", sqlStat.clobOpenCount); - } + if (sqlStat.updateCount > 0) { + sqlStatMap.put("updateCount", sqlStat.updateCount); + sqlStatMap.put("updateCountMax", sqlStat.updateCountMax); + sqlStatMap.put("updateHistogram", rtrim(sqlStat.getUpdateHistogram())); + } - if (sqlStat.blobOpenCount > 0) { - sqlStatMap.put("blobOpenCount", sqlStat.blobOpenCount); + 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); diff --git a/src/main/java/com/alibaba/druid/pool/DruidDataSourceStatValue.java b/src/main/java/com/alibaba/druid/pool/DruidDataSourceStatValue.java index 524bd2726c..5f7f717962 100644 --- a/src/main/java/com/alibaba/druid/pool/DruidDataSourceStatValue.java +++ b/src/main/java/com/alibaba/druid/pool/DruidDataSourceStatValue.java @@ -43,7 +43,7 @@ public class DruidDataSourceStatValue { public boolean testWhileIdle; public boolean defaultAutoCommit; public boolean defaultReadOnly; - public int defaultTransactionIsolation; + public Integer defaultTransactionIsolation; public int activeCount; public int activePeak; diff --git a/src/main/java/com/alibaba/druid/stat/JdbcSqlStat.java b/src/main/java/com/alibaba/druid/stat/JdbcSqlStat.java index 7d5943f256..74a9dc0fbf 100644 --- a/src/main/java/com/alibaba/druid/stat/JdbcSqlStat.java +++ b/src/main/java/com/alibaba/druid/stat/JdbcSqlStat.java @@ -382,6 +382,7 @@ public final class JdbcSqlStat implements JdbcSqlStatMBean { public JdbcSqlStatValue getValueAndReset() { JdbcSqlStatValue val = new JdbcSqlStatValue(); + val.sql = sql; val.executeLastStartTime = executeLastStartTime; executeLastStartTime = 0; diff --git a/src/main/java/com/alibaba/druid/support/logging/SLF4JImpl.java b/src/main/java/com/alibaba/druid/support/logging/SLF4JImpl.java index 81fc923eaa..cc5ab7e659 100644 --- a/src/main/java/com/alibaba/druid/support/logging/SLF4JImpl.java +++ b/src/main/java/com/alibaba/druid/support/logging/SLF4JImpl.java @@ -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 diff --git a/src/main/java/com/alibaba/druid/util/Histogram.java b/src/main/java/com/alibaba/druid/util/Histogram.java index 468985297b..6934202b91 100644 --- a/src/main/java/com/alibaba/druid/util/Histogram.java +++ b/src/main/java/com/alibaba/druid/util/Histogram.java @@ -76,12 +76,13 @@ 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; } diff --git a/src/main/java/com/alibaba/druid/util/JdbcSqlStatUtils.java b/src/main/java/com/alibaba/druid/util/JdbcSqlStatUtils.java index ba3ab0b267..1e9c99cb58 100644 --- a/src/main/java/com/alibaba/druid/util/JdbcSqlStatUtils.java +++ b/src/main/java/com/alibaba/druid/util/JdbcSqlStatUtils.java @@ -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; + } } diff --git a/src/test/java/com/alibaba/druid/bvt/pool/TimeBetweenLogStatsMillisTest2.java b/src/test/java/com/alibaba/druid/bvt/pool/TimeBetweenLogStatsMillisTest2.java new file mode 100644 index 0000000000..5eef91891b --- /dev/null +++ b/src/test/java/com/alibaba/druid/bvt/pool/TimeBetweenLogStatsMillisTest2.java @@ -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()); + } +} diff --git a/src/test/java/com/alibaba/druid/bvt/pool/TimeBetweenLogStatsMillisTest3.java b/src/test/java/com/alibaba/druid/bvt/pool/TimeBetweenLogStatsMillisTest3.java new file mode 100644 index 0000000000..4373f3b495 --- /dev/null +++ b/src/test/java/com/alibaba/druid/bvt/pool/TimeBetweenLogStatsMillisTest3.java @@ -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()); + } +}