diff --git a/src/main/java/com/alibaba/druid/filter/stat/StatFilter.java b/src/main/java/com/alibaba/druid/filter/stat/StatFilter.java index 7e6086e4dc..19b57336eb 100644 --- a/src/main/java/com/alibaba/druid/filter/stat/StatFilter.java +++ b/src/main/java/com/alibaba/druid/filter/stat/StatFilter.java @@ -68,6 +68,10 @@ public class StatFilter extends FilterEventAdapter implements StatFilterMBean { public void setConnectionStackTraceEnable(boolean connectionStackTraceEnable) { this.connectionStackTraceEnable = connectionStackTraceEnable; } + + public JdbcDataSourceStat getDataSourceStat() { + return this.dataSourceStat; + } public void reset() { dataSourceStat.reset(); diff --git a/src/main/java/com/alibaba/druid/proxy/jdbc/DataSourceProxyImpl.java b/src/main/java/com/alibaba/druid/proxy/jdbc/DataSourceProxyImpl.java index 34355dff85..ad2db8ae28 100644 --- a/src/main/java/com/alibaba/druid/proxy/jdbc/DataSourceProxyImpl.java +++ b/src/main/java/com/alibaba/druid/proxy/jdbc/DataSourceProxyImpl.java @@ -15,6 +15,8 @@ */ package com.alibaba.druid.proxy.jdbc; +import java.io.PrintWriter; +import java.io.StringWriter; import java.sql.Driver; import java.sql.SQLException; import java.util.ArrayList; @@ -37,6 +39,8 @@ import javax.security.auth.callback.PasswordCallback; import com.alibaba.druid.filter.Filter; import com.alibaba.druid.filter.FilterChain; import com.alibaba.druid.filter.FilterChainImpl; +import com.alibaba.druid.filter.stat.StatFilter; +import com.alibaba.druid.stat.JdbcDataSourceStat; import com.alibaba.druid.util.JdbcUtils; /** @@ -183,20 +187,48 @@ public class DataSourceProxyImpl implements DataSourceProxy, DataSourceProxyImpl return COMPOSITE_TYPE; } - OpenType[] indexTypes = new OpenType[] { SimpleType.LONG, SimpleType.STRING, SimpleType.STRING, - new ArrayType>(SimpleType.STRING, false), SimpleType.DATE, - // - SimpleType.STRING, SimpleType.STRING, SimpleType.INTEGER, SimpleType.INTEGER, SimpleType.STRING }; + OpenType[] indexTypes = new OpenType[] { // + SimpleType.LONG, SimpleType.STRING, SimpleType.STRING, new ArrayType>(SimpleType.STRING, false), SimpleType.DATE, // + SimpleType.STRING, SimpleType.STRING, SimpleType.INTEGER, SimpleType.INTEGER, SimpleType.STRING // + , SimpleType.LONG, SimpleType.LONG, SimpleType.LONG, SimpleType.LONG, SimpleType.LONG // + , SimpleType.DATE, SimpleType.LONG, SimpleType.DATE, SimpleType.STRING, SimpleType.STRING // + , SimpleType.LONG, SimpleType.LONG, SimpleType.LONG, SimpleType.LONG, SimpleType.INTEGER // + , SimpleType.INTEGER, SimpleType.LONG, SimpleType.LONG, SimpleType.DATE, SimpleType.STRING // + , SimpleType.STRING, SimpleType.LONG, SimpleType.INTEGER, SimpleType.DATE, SimpleType.LONG // + , SimpleType.LONG, SimpleType.INTEGER, SimpleType.INTEGER, SimpleType.LONG, SimpleType.DATE // + , + // + }; + + String[] indexNames = { "ID", "URL", "Name", "FilterClasses", "CreatedTime", // + "RawUrl", "RawDriverClassName", "RawDriverMajorVersion", "RawDriverMinorVersion", "Properties" // + , "ConnectionCount", "ConnectionCountMax", "ConnectionCloseCount", "ConnectionCommitCount", "ConnectionRollbackCount" // + , "ConnectLastTime", "ConnectErrorCount", "ConnectLastErrorTime", "ConnectLastErrorMessage", "ConnectLastErrorStackTrace" // + , "StatementCreateCount", "StatementPrepareCount", "StatementPreCallCount", "StatementExecuteCount", "StatementRunningCount" // + , "StatementConcurrentMax", "StatementCloseCount", "StatementErrorCount", "StatementLastErrorTime", "StatementLastErrorMessage" // + , "StatementLastErrorStackTrace", "StatementExecuteMillis", "ConnectingCount", "StatementExecuteLastTime", "ResultSetCloseCount" // + , "ResultSetOpenCount", "ResultSetOpenningCount", "ResultSetOpenningMax", "ResultSetFetchRowCount", "ResultSetLastOpenTime" + // + }; - String[] indexNames = { "ID", "URL", "Name", "FilterClasses", "CreatedTime", "RawUrl", "RawDriverClassName", "RawDriverMajorVersion", - "RawDriverMinorVersion", "Properties" }; String[] indexDescriptions = indexNames; - COMPOSITE_TYPE = new CompositeType("SqlStatistic", "Sql Statistic", indexNames, indexDescriptions, indexTypes); + COMPOSITE_TYPE = new CompositeType("DataSourceStatistic", "DataSource Statistic", indexNames, indexDescriptions, indexTypes); return COMPOSITE_TYPE; } public CompositeDataSupport getCompositeData() throws JMException { + StatFilter statFilter = null; + JdbcDataSourceStat stat = null; + for (Filter filter : this.getFilters()) { + if (filter instanceof StatFilter) { + statFilter = (StatFilter) filter; + } + } + if (statFilter != null) { + stat = statFilter.getDataSourceStat(); + } + Map map = new HashMap(); map.put("ID", id); @@ -211,6 +243,100 @@ public class DataSourceProxyImpl implements DataSourceProxy, DataSourceProxyImpl map.put("RawDriverMinorVersion", getRawDriverMinorVersion()); map.put("Properties", getProperties()); + if (stat != null) { + map.put("ConnectionCount", stat.getConnectionActiveCount()); + map.put("ConnectionCountMax", stat.getConnectionStat().getActiveMax()); + map.put("ConnectionCloseCount", stat.getConnectionStat().getCloseCount()); + map.put("ConnectionCommitCount", stat.getConnectionStat().getCommitCount()); + map.put("ConnectionRollbackCount", stat.getConnectionStat().getRollbackCount()); + + map.put("ConnectLastTime", stat.getConnectionStat().getLastConnectTime()); + map.put("ConnectErrorCount", stat.getConnectionStat().getErrorCount()); + Throwable lastConnectionError = stat.getConnectionStat().getLastError(); + if (lastConnectionError != null) { + map.put("ConnectLastErrorTime", stat.getConnectionStat().getLastErrorTime()); + map.put("ConnectLastErrorMessage", lastConnectionError.getMessage()); + StringWriter buf = new StringWriter(); + lastConnectionError.printStackTrace(new PrintWriter(buf)); + map.put("ConnectLastErrorStackTrace", buf.toString()); + } else { + map.put("ConnectLastErrorTime", null); + map.put("ConnectLastErrorMessage", null); + map.put("ConnectLastErrorStackTrace", null); + } + + map.put("StatementCreateCount", stat.getStatementStat().getCreateCount()); + map.put("StatementPrepareCount", stat.getStatementStat().getPrepareCount()); + map.put("StatementPreCallCount", stat.getStatementStat().getPrepareCallCount()); + map.put("StatementExecuteCount", stat.getStatementStat().getExecuteCount()); + map.put("StatementRunningCount", stat.getStatementStat().getRunningCount()); + + map.put("StatementConcurrentMax", stat.getStatementStat().getConcurrentMax()); + map.put("StatementCloseCount", stat.getStatementStat().getCloseCount()); + map.put("StatementErrorCount", stat.getStatementStat().getErrorCount()); + Throwable lastStatementError = stat.getStatementStat().getLastException(); + if (lastStatementError != null) { + map.put("StatementLastErrorTime", stat.getStatementStat().getLastErrorTime()); + map.put("StatementLastErrorMessage", lastStatementError.getMessage()); + + StringWriter buf = new StringWriter(); + lastStatementError.printStackTrace(new PrintWriter(buf)); + map.put("StatementLastErrorStackTrace", buf.toString()); + } else { + map.put("StatementLastErrorTime", null); + map.put("StatementLastErrorMessage", null); + + map.put("StatementLastErrorStackTrace", null); + } + map.put("StatementExecuteMillis", stat.getStatementStat().getMillisTotal()); + map.put("StatementExecuteLastTime", stat.getStatementStat().getExecuteLastTime()); + map.put("ConnectingCount", stat.getConnectionStat().getRunningCount()); + map.put("ResultSetCloseCount", stat.getResultSetStat().getCloseCount()); + + map.put("ResultSetOpenCount", stat.getResultSetStat().getOpenCount()); + map.put("ResultSetOpenningCount", stat.getResultSetStat().getRunningCount()); + map.put("ResultSetOpenningMax", stat.getResultSetStat().getConcurrentMax()); + map.put("ResultSetFetchRowCount", stat.getResultSetStat().getFetchRowCount()); + map.put("ResultSetLastOpenTime", stat.getResultSetStat().getLastOpenTime()); + + } else { + map.put("ConnectionCount", null); + map.put("ConnectionCountMax", null); + map.put("ConnectionCloseCount", null); + map.put("ConnectionCommitCount", null); + map.put("ConnectionRollbackCount", null); + + map.put("ConnectLastTime", null); + map.put("ConnectErrorCount", null); + map.put("ConnectLastErrorTime", null); + map.put("ConnectLastErrorMessage", null); + map.put("ConnectLastErrorStackTrace", null); + + map.put("StatementCreateCount", null); + map.put("StatementPrepareCount", null); + map.put("StatementPreCallCount", null); + map.put("StatementExecuteCount", null); + map.put("StatementRunningCount", null); + + map.put("StatementConcurrentMax", null); + map.put("StatementCloseCount", null); + map.put("StatementErrorCount", null); + map.put("StatementLastErrorTime", null); + map.put("StatementLastErrorMessage", null); + + map.put("StatementLastErrorStackTrace", null); + map.put("StatementExecuteMillis", null); + map.put("ConnectingCount", null); + map.put("StatementExecuteLastTime", null); + map.put("ResultSetCloseCount", null); + + map.put("ResultSetOpenCount", null); + map.put("ResultSetOpenningCount", null); + map.put("ResultSetOpenningMax", null); + map.put("ResultSetFetchRowCount", null); + map.put("ResultSetLastOpenTime", null); + } + return new CompositeDataSupport(getCompositeType(), map); } diff --git a/src/main/java/com/alibaba/druid/stat/JdbcResultSetStat.java b/src/main/java/com/alibaba/druid/stat/JdbcResultSetStat.java index 56403c837d..61a31cd98d 100644 --- a/src/main/java/com/alibaba/druid/stat/JdbcResultSetStat.java +++ b/src/main/java/com/alibaba/druid/stat/JdbcResultSetStat.java @@ -21,10 +21,10 @@ import java.util.concurrent.atomic.AtomicLong; public class JdbcResultSetStat implements JdbcResultSetStatMBean { - private final AtomicInteger concurrentCount = new AtomicInteger(); - private final AtomicInteger concurrentMax = new AtomicInteger(); + private final AtomicInteger openningCount = new AtomicInteger(); + private final AtomicInteger opeeningtMax = new AtomicInteger(); - private final AtomicLong count = new AtomicLong(); + private final AtomicLong openCount = new AtomicLong(); private final AtomicLong errorCount = new AtomicLong(); private final AtomicLong nanoTotal = new AtomicLong(); @@ -37,9 +37,9 @@ public class JdbcResultSetStat implements JdbcResultSetStatMBean { private final AtomicLong closeCount = new AtomicLong(0); // ResultSet打开的计数 public void reset() { - concurrentCount.set(0); - concurrentMax.set(0); - count.set(0); + openningCount.set(0); + opeeningtMax.set(0); + openCount.set(0); errorCount.set(0); nanoTotal.set(0); lastError = null; @@ -48,12 +48,12 @@ public class JdbcResultSetStat implements JdbcResultSetStatMBean { } public void beforeOpen() { - int invoking = concurrentCount.incrementAndGet(); + int invoking = openningCount.incrementAndGet(); for (;;) { - int max = concurrentMax.get(); + int max = opeeningtMax.get(); if (invoking > max) { - if (concurrentMax.compareAndSet(max, invoking)) { + if (opeeningtMax.compareAndSet(max, invoking)) { break; } else { continue; @@ -63,7 +63,7 @@ public class JdbcResultSetStat implements JdbcResultSetStatMBean { } } - count.incrementAndGet(); + openCount.incrementAndGet(); lastSampleTime = System.currentTimeMillis(); } @@ -72,18 +72,18 @@ public class JdbcResultSetStat implements JdbcResultSetStatMBean { } public int getRunningCount() { - return concurrentCount.get(); + return openningCount.get(); } public int getConcurrentMax() { - return concurrentMax.get(); + return opeeningtMax.get(); } public long getOpenCount() { - return count.get(); + return openCount.get(); } - public Date getLastConnectTime() { + public Date getLastOpenTime() { if (lastSampleTime == 0) { return null; } @@ -96,7 +96,7 @@ public class JdbcResultSetStat implements JdbcResultSetStatMBean { } public void afterClose(long nanoSpan) { - concurrentCount.decrementAndGet(); + openningCount.decrementAndGet(); nanoTotal.addAndGet(nanoSpan); } diff --git a/src/main/java/com/alibaba/druid/stat/JdbcStatementStat.java b/src/main/java/com/alibaba/druid/stat/JdbcStatementStat.java index e39101fc9a..f5026fd8f3 100644 --- a/src/main/java/com/alibaba/druid/stat/JdbcStatementStat.java +++ b/src/main/java/com/alibaba/druid/stat/JdbcStatementStat.java @@ -29,9 +29,9 @@ public class JdbcStatementStat implements JdbcStatementStatMBean { private final AtomicLong createCount = new AtomicLong(0); // 执行createStatement的计数 private final AtomicLong prepareCount = new AtomicLong(0); // 执行parepareStatement的计数 private final AtomicLong prepareCallCount = new AtomicLong(0); // 执行preCall的计数 - private final AtomicLong closeCounter = new AtomicLong(0); // Statement关闭的计数 + private final AtomicLong closeCount = new AtomicLong(0); // Statement关闭的计数 - private final AtomicInteger concurrentCount = new AtomicInteger(); + private final AtomicInteger runningCount = new AtomicInteger(); private final AtomicInteger concurrentMax = new AtomicInteger(); private final AtomicLong count = new AtomicLong(); @@ -45,7 +45,7 @@ public class JdbcStatementStat implements JdbcStatementStatMBean { private long lastSampleTime = 0; public void reset() { - concurrentCount.set(0); + runningCount.set(0); concurrentMax.set(0); count.set(0); errorCount.set(0); @@ -57,11 +57,11 @@ public class JdbcStatementStat implements JdbcStatementStatMBean { createCount.set(0); prepareCount.set(0); prepareCallCount.set(0); - closeCounter.set(0); + closeCount.set(0); } public void beforeExecute() { - int invoking = concurrentCount.incrementAndGet(); + int invoking = runningCount.incrementAndGet(); for (;;) { int max = concurrentMax.get(); @@ -85,7 +85,7 @@ public class JdbcStatementStat implements JdbcStatementStatMBean { } public int getRunningCount() { - return concurrentCount.get(); + return runningCount.get(); } public int getConcurrentMax() { @@ -107,9 +107,13 @@ public class JdbcStatementStat implements JdbcStatementStatMBean { public long getNanoTotal() { return nanoTotal.get(); } + + public long getMillisTotal() { + return nanoTotal.get() / (1000 * 1000); + } public void afterExecute(long nanoSpan) { - concurrentCount.decrementAndGet(); + runningCount.decrementAndGet(); nanoTotal.addAndGet(nanoSpan); } @@ -134,7 +138,7 @@ public class JdbcStatementStat implements JdbcStatementStatMBean { @Override public long getCloseCount() { - return closeCounter.get(); + return closeCount.get(); } @Override @@ -180,7 +184,7 @@ public class JdbcStatementStat implements JdbcStatementStatMBean { } public void incrementStatementCloseCounter() { - closeCounter.incrementAndGet(); + closeCount.incrementAndGet(); } public static class Entry { diff --git a/src/test/java/com/alibaba/druid/proxy/TestOracle.java b/src/test/java/com/alibaba/druid/proxy/TestOracle.java new file mode 100644 index 0000000000..c18c1389df --- /dev/null +++ b/src/test/java/com/alibaba/druid/proxy/TestOracle.java @@ -0,0 +1,40 @@ +package com.alibaba.druid.proxy; + +import java.sql.Connection; +import java.sql.DriverManager; +import java.sql.ResultSet; +import java.sql.Statement; + +import javax.management.openmbean.TabularData; + +import junit.framework.TestCase; + +import com.alibaba.druid.stat.JdbcStatManager; +import com.alibaba.fastjson.JSON; + +public class TestOracle extends TestCase { + private String jdbcUrl; + private String user; + private String password; + + public void setUp() throws Exception { + jdbcUrl = "jdbc:wrap-jdbc:filters=default:name=oracleTest:jdbc:oracle:thin:@10.20.149.85:1521:ocnauto"; + jdbcUrl = "jdbc:wrap-jdbc:filters=default:name=oracleTest:jdbc:mock:xx"; + user = "alibaba"; + password = "ccbuauto"; + } + + public void test_0 () throws Exception { + Connection conn = DriverManager.getConnection(jdbcUrl, user, password); + Statement stmt = conn.createStatement(); + ResultSet rs = stmt.executeQuery("SELECT 1 FROM DUAL"); + rs.next(); + rs.close(); + stmt.close(); + conn.close(); + + TabularData dataSourcesList = JdbcStatManager.getInstance().getDataSourceList(); + String text = JSON.toJSONString(dataSourcesList); + System.out.println(JSON.toJSONString(JSON.parse(text), true)); + } +}