From 9b63e9ece2e0b458e775c77b9e7001a483c291ab Mon Sep 17 00:00:00 2001 From: wenshao Date: Mon, 27 Aug 2012 22:50:25 +0800 Subject: [PATCH 1/3] add stat readStringLength --- .../alibaba/druid/filter/stat/StatFilter.java | 47 ++++++++++++++----- .../druid/proxy/jdbc/ResultSetProxy.java | 4 ++ .../druid/proxy/jdbc/ResultSetProxyImpl.java | 18 +++++-- .../com/alibaba/druid/stat/JdbcSqlStat.java | 23 +++++++-- .../support/http/resources/sql-detail.html | 17 ++++++- 5 files changed, 88 insertions(+), 21 deletions(-) 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 c9bb2dfbf1..3698e0760e 100644 --- a/src/main/java/com/alibaba/druid/filter/stat/StatFilter.java +++ b/src/main/java/com/alibaba/druid/filter/stat/StatFilter.java @@ -573,6 +573,7 @@ public class StatFilter extends FilterEventAdapter implements StatFilterMBean { sqlStat.addFetchRowCount(fetchRowCount); long stmtExecuteNano = resultSet.getStatementProxy().getLastExecuteTimeNano(); sqlStat.addResultSetHoldTimeNano(stmtExecuteNano, nanos); + sqlStat.addStringReadLength(resultSet.getReadStringLength()); } } @@ -761,10 +762,10 @@ public class StatFilter extends FilterEventAdapter implements StatFilterMBean { if (obj instanceof Clob) { clobOpenAfter(chain.getDataSource().getDataSourceStat(), result, (ClobProxy) obj); - } - - if (obj instanceof Blob) { + } else if (obj instanceof Blob) { blobOpenAfter(chain.getDataSource().getDataSourceStat(), result, (Blob) obj); + } else if (obj instanceof String) { + result.addReadStringLength(((String) obj).length()); } return obj; @@ -777,10 +778,10 @@ public class StatFilter extends FilterEventAdapter implements StatFilterMBean { if (obj instanceof Clob) { clobOpenAfter(chain.getDataSource().getDataSourceStat(), result, (ClobProxy) obj); - } - - if (obj instanceof Blob) { + } else if (obj instanceof Blob) { blobOpenAfter(chain.getDataSource().getDataSourceStat(), result, (Blob) obj); + } else if (obj instanceof String) { + result.addReadStringLength(((String) obj).length()); } return obj; @@ -792,10 +793,10 @@ public class StatFilter extends FilterEventAdapter implements StatFilterMBean { if (obj instanceof Clob) { clobOpenAfter(chain.getDataSource().getDataSourceStat(), result, (ClobProxy) obj); - } - - if (obj instanceof Blob) { + } else if (obj instanceof Blob) { blobOpenAfter(chain.getDataSource().getDataSourceStat(), result, (Blob) obj); + } else if (obj instanceof String) { + result.addReadStringLength(((String) obj).length()); } return obj; @@ -808,10 +809,10 @@ public class StatFilter extends FilterEventAdapter implements StatFilterMBean { if (obj instanceof Clob) { clobOpenAfter(chain.getDataSource().getDataSourceStat(), result, (ClobProxy) obj); - } - - if (obj instanceof Blob) { + } else if (obj instanceof Blob) { blobOpenAfter(chain.getDataSource().getDataSourceStat(), result, (Blob) obj); + } else if (obj instanceof String) { + result.addReadStringLength(((String) obj).length()); } return obj; @@ -915,4 +916,26 @@ public class StatFilter extends FilterEventAdapter implements StatFilterMBean { StatFilterContext.getInstance().clob_open(); } + + @Override + public String resultSet_getString(FilterChain chain, ResultSetProxy result, int columnIndex) throws SQLException { + String value = chain.resultSet_getString(result, columnIndex); + + if (value != null) { + result.addReadStringLength(value.length()); + } + + return value; + } + + @Override + public String resultSet_getString(FilterChain chain, ResultSetProxy result, String columnLabel) throws SQLException { + String value = chain.resultSet_getString(result, columnLabel); + + if (value != null) { + result.addReadStringLength(value.length()); + } + + return value; + } } diff --git a/src/main/java/com/alibaba/druid/proxy/jdbc/ResultSetProxy.java b/src/main/java/com/alibaba/druid/proxy/jdbc/ResultSetProxy.java index f6a6ff7ef2..e7bd92d6ca 100644 --- a/src/main/java/com/alibaba/druid/proxy/jdbc/ResultSetProxy.java +++ b/src/main/java/com/alibaba/druid/proxy/jdbc/ResultSetProxy.java @@ -43,4 +43,8 @@ public interface ResultSetProxy extends ResultSet, WrapperProxy { void setConstructNano(); int getCloseCount(); + + void addReadStringLength(int length); + + long getReadStringLength(); } diff --git a/src/main/java/com/alibaba/druid/proxy/jdbc/ResultSetProxyImpl.java b/src/main/java/com/alibaba/druid/proxy/jdbc/ResultSetProxyImpl.java index 45017f8596..6e8791f065 100644 --- a/src/main/java/com/alibaba/druid/proxy/jdbc/ResultSetProxyImpl.java +++ b/src/main/java/com/alibaba/druid/proxy/jdbc/ResultSetProxyImpl.java @@ -51,11 +51,13 @@ public class ResultSetProxyImpl extends WrapperProxyImpl implements ResultSetPro private final StatementProxy statement; private final String sql; - protected int cursorIndex = 0; - protected int fetchRowCount = 0; + protected int cursorIndex = 0; + protected int fetchRowCount = 0; protected long constructNano; protected final JdbcSqlStat sqlStat; - private int closeCount = 0; + private int closeCount = 0; + + private long readStringLength = 0; public ResultSetProxyImpl(StatementProxy statement, ResultSet resultSet, long id, String sql){ super(resultSet, id); @@ -1078,4 +1080,14 @@ public class ResultSetProxyImpl extends WrapperProxyImpl implements ResultSetPro return closeCount; } + @Override + public void addReadStringLength(int length) { + this.readStringLength += length; + } + + @Override + public long getReadStringLength() { + return readStringLength; + } + } diff --git a/src/main/java/com/alibaba/druid/stat/JdbcSqlStat.java b/src/main/java/com/alibaba/druid/stat/JdbcSqlStat.java index 01770643e5..6a89f230fc 100644 --- a/src/main/java/com/alibaba/druid/stat/JdbcSqlStat.java +++ b/src/main/java/com/alibaba/druid/stat/JdbcSqlStat.java @@ -77,6 +77,7 @@ public final class JdbcSqlStat implements JdbcSqlStatMBean { private final AtomicLong clobOpenCount = new AtomicLong(); private final AtomicLong blobOpenCount = new AtomicLong(); + private final AtomicLong stringReadLength = new AtomicLong(); private final Histogram histogram = new Histogram(new long[] { // // @@ -226,6 +227,7 @@ public final class JdbcSqlStat implements JdbcSqlStatMBean { blobOpenCount.set(0); clobOpenCount.set(0); + stringReadLength.set(0); } public long getConcurrentMax() { @@ -274,14 +276,22 @@ public final class JdbcSqlStat implements JdbcSqlStatMBean { public void incrementClobOpenCount() { clobOpenCount.incrementAndGet(); } - + public long getBlobOpenCount() { return blobOpenCount.get(); } - + public void incrementBlobOpenCount() { blobOpenCount.incrementAndGet(); } + + public long getStringReadLength() { + return stringReadLength.get(); + } + + public void addStringReadLength(long length) { + this.stringReadLength.addAndGet(length); + } public long getId() { return id; @@ -505,9 +515,10 @@ public final class JdbcSqlStat implements JdbcSqlStatMBean { SimpleType.LONG, // SimpleType.LONG, // SimpleType.LONG, // - + // 35 - SimpleType.LONG, // + SimpleType.LONG, // }; @@ -560,9 +571,10 @@ public final class JdbcSqlStat implements JdbcSqlStatMBean { "EffectedRowCountMax", // "FetchRowCountMax", // "ClobOpenCount", - + // 35 - "BlobOpenCount", + "StringReadLength", // }; @@ -634,8 +646,9 @@ public final class JdbcSqlStat implements JdbcSqlStatMBean { map.put("EffectedRowCountMax", getUpdateCountMax()); // 32 map.put("FetchRowCountMax", getFetchRowCountMax()); // 33 map.put("ClobOpenCount", getClobOpenCount()); // 34 - + map.put("BlobOpenCount", getBlobOpenCount()); // 35 + map.put("StringReadLength", getStringReadLength()); // 36 return map; } diff --git a/src/main/resources/support/http/resources/sql-detail.html b/src/main/resources/support/http/resources/sql-detail.html index 8cfaf38f1d..d1312510eb 100644 --- a/src/main/resources/support/http/resources/sql-detail.html +++ b/src/main/resources/support/http/resources/sql-detail.html @@ -85,7 +85,7 @@
-

Batch View:

+

Other View:

@@ -95,6 +95,18 @@ + + + + + + + + + + + +
BatchSizeMaxBatchSizeTotal
BlobOpenCount
ClobOpenCount
StringReadLength
Close @@ -141,6 +153,9 @@ $("#BatchSizeMax").text(sqlInfo.BatchSizeMax) $("#BatchSizeTotal").text(sqlInfo.BatchSizeTotal) + $("#BlobOpenCount").text(sqlInfo.BlobOpenCount) + $("#ClobOpenCount").text(sqlInfo.ClobOpenCount) + $("#StringReadLength").text(sqlInfo.StringReadLength) }, dataType: "json" }); From 7feed4ad47dc373de3350cafc15da36504d427d5 Mon Sep 17 00:00:00 2001 From: wenshao Date: Tue, 28 Aug 2012 06:03:05 +0800 Subject: [PATCH 2/3] add readBytes Count --- .../alibaba/druid/filter/stat/StatFilter.java | 48 ++++++++++++++----- .../druid/proxy/jdbc/ResultSetProxy.java | 4 ++ .../druid/proxy/jdbc/ResultSetProxyImpl.java | 11 +++++ .../com/alibaba/druid/stat/JdbcSqlStat.java | 33 +++++++++---- .../support/http/resources/sql-detail.html | 11 +++-- 5 files changed, 81 insertions(+), 26 deletions(-) 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 3698e0760e..d90d475a56 100644 --- a/src/main/java/com/alibaba/druid/filter/stat/StatFilter.java +++ b/src/main/java/com/alibaba/druid/filter/stat/StatFilter.java @@ -709,26 +709,26 @@ public class StatFilter extends FilterEventAdapter implements StatFilterMBean { return blob; } - + @Override public Blob resultSet_getBlob(FilterChain chain, ResultSetProxy result, int columnIndex) throws SQLException { Blob blob = chain.resultSet_getBlob(result, columnIndex); - + if (blob != null) { blobOpenAfter(chain.getDataSource().getDataSourceStat(), result, blob); } - + return blob; } @Override public Blob resultSet_getBlob(FilterChain chain, ResultSetProxy result, String columnLabel) throws SQLException { Blob blob = chain.resultSet_getBlob(result, columnLabel); - + if (blob != null) { blobOpenAfter(chain.getDataSource().getDataSourceStat(), result, blob); } - + return blob; } @@ -826,7 +826,7 @@ public class StatFilter extends FilterEventAdapter implements StatFilterMBean { if (obj instanceof Clob) { clobOpenAfter(chain.getDataSource().getDataSourceStat(), statement, (ClobProxy) obj); } - + if (obj instanceof Blob) { blobOpenAfter(chain.getDataSource().getDataSourceStat(), statement, (Blob) obj); } @@ -882,7 +882,7 @@ public class StatFilter extends FilterEventAdapter implements StatFilterMBean { return obj; } - + private void blobOpenAfter(JdbcDataSourceStat dataSourceStat, ResultSetProxy rs, Blob blob) { blobOpenAfter(dataSourceStat, rs.getStatementProxy(), blob); } @@ -893,7 +893,7 @@ public class StatFilter extends FilterEventAdapter implements StatFilterMBean { private void blobOpenAfter(JdbcDataSourceStat dataSourceStat, StatementProxy stmt, Blob blob) { dataSourceStat.incrementBlobOpenCount(); - + if (stmt != null) { JdbcSqlStat sqlStat = stmt.getSqlStat(); if (sqlStat != null) { @@ -916,26 +916,48 @@ public class StatFilter extends FilterEventAdapter implements StatFilterMBean { StatFilterContext.getInstance().clob_open(); } - + @Override public String resultSet_getString(FilterChain chain, ResultSetProxy result, int columnIndex) throws SQLException { String value = chain.resultSet_getString(result, columnIndex); - + if (value != null) { result.addReadStringLength(value.length()); } - + return value; } @Override public String resultSet_getString(FilterChain chain, ResultSetProxy result, String columnLabel) throws SQLException { String value = chain.resultSet_getString(result, columnLabel); - + if (value != null) { result.addReadStringLength(value.length()); } - + + return value; + } + + @Override + public byte[] resultSet_getBytes(FilterChain chain, ResultSetProxy result, int columnIndex) throws SQLException { + byte[] value = chain.resultSet_getBytes(result, columnIndex); + + if (value != null) { + result.addReadBytesLength(value.length); + } + + return value; + } + + @Override + public byte[] resultSet_getBytes(FilterChain chain, ResultSetProxy result, String columnLabel) throws SQLException { + byte[] value = chain.resultSet_getBytes(result, columnLabel); + + if (value != null) { + result.addReadBytesLength(value.length); + } + return value; } } diff --git a/src/main/java/com/alibaba/druid/proxy/jdbc/ResultSetProxy.java b/src/main/java/com/alibaba/druid/proxy/jdbc/ResultSetProxy.java index e7bd92d6ca..43d5521051 100644 --- a/src/main/java/com/alibaba/druid/proxy/jdbc/ResultSetProxy.java +++ b/src/main/java/com/alibaba/druid/proxy/jdbc/ResultSetProxy.java @@ -47,4 +47,8 @@ public interface ResultSetProxy extends ResultSet, WrapperProxy { void addReadStringLength(int length); long getReadStringLength(); + + void addReadBytesLength(int length); + + long getReadBytesLength(); } diff --git a/src/main/java/com/alibaba/druid/proxy/jdbc/ResultSetProxyImpl.java b/src/main/java/com/alibaba/druid/proxy/jdbc/ResultSetProxyImpl.java index 6e8791f065..3cc53b278b 100644 --- a/src/main/java/com/alibaba/druid/proxy/jdbc/ResultSetProxyImpl.java +++ b/src/main/java/com/alibaba/druid/proxy/jdbc/ResultSetProxyImpl.java @@ -58,6 +58,7 @@ public class ResultSetProxyImpl extends WrapperProxyImpl implements ResultSetPro private int closeCount = 0; private long readStringLength = 0; + private long readBytesLength = 0; public ResultSetProxyImpl(StatementProxy statement, ResultSet resultSet, long id, String sql){ super(resultSet, id); @@ -1089,5 +1090,15 @@ public class ResultSetProxyImpl extends WrapperProxyImpl implements ResultSetPro public long getReadStringLength() { return readStringLength; } + + @Override + public void addReadBytesLength(int length) { + this.readBytesLength += length; + } + + @Override + public long getReadBytesLength() { + return readBytesLength; + } } diff --git a/src/main/java/com/alibaba/druid/stat/JdbcSqlStat.java b/src/main/java/com/alibaba/druid/stat/JdbcSqlStat.java index 6a89f230fc..2cae8a2e21 100644 --- a/src/main/java/com/alibaba/druid/stat/JdbcSqlStat.java +++ b/src/main/java/com/alibaba/druid/stat/JdbcSqlStat.java @@ -77,7 +77,8 @@ public final class JdbcSqlStat implements JdbcSqlStatMBean { private final AtomicLong clobOpenCount = new AtomicLong(); private final AtomicLong blobOpenCount = new AtomicLong(); - private final AtomicLong stringReadLength = new AtomicLong(); + private final AtomicLong readStringLength = new AtomicLong(); + private final AtomicLong readBytesLength = new AtomicLong(); private final Histogram histogram = new Histogram(new long[] { // // @@ -227,7 +228,8 @@ public final class JdbcSqlStat implements JdbcSqlStatMBean { blobOpenCount.set(0); clobOpenCount.set(0); - stringReadLength.set(0); + readStringLength.set(0); + readBytesLength.set(0); } public long getConcurrentMax() { @@ -284,13 +286,21 @@ public final class JdbcSqlStat implements JdbcSqlStatMBean { public void incrementBlobOpenCount() { blobOpenCount.incrementAndGet(); } - - public long getStringReadLength() { - return stringReadLength.get(); + + public long getReadStringLength() { + return readStringLength.get(); } - + public void addStringReadLength(long length) { - this.stringReadLength.addAndGet(length); + this.readStringLength.addAndGet(length); + } + + public long getReadBytesLength() { + return readBytesLength.get(); + } + + public void addReadBytesLength(int length) { + this.readBytesLength.addAndGet(length); } public long getId() { @@ -519,6 +529,7 @@ public final class JdbcSqlStat implements JdbcSqlStatMBean { // 35 - SimpleType.LONG, // SimpleType.LONG, // + SimpleType.LONG, // }; @@ -573,8 +584,9 @@ public final class JdbcSqlStat implements JdbcSqlStatMBean { "ClobOpenCount", // 35 - - "BlobOpenCount", - "StringReadLength", + "BlobOpenCount", // + "ReadStringLength", // + "ReadBytesLength", // }; @@ -648,7 +660,8 @@ public final class JdbcSqlStat implements JdbcSqlStatMBean { map.put("ClobOpenCount", getClobOpenCount()); // 34 map.put("BlobOpenCount", getBlobOpenCount()); // 35 - map.put("StringReadLength", getStringReadLength()); // 36 + map.put("ReadStringLength", getReadStringLength()); // 36 + map.put("ReadBytesLength", getReadBytesLength()); // 37 return map; } diff --git a/src/main/resources/support/http/resources/sql-detail.html b/src/main/resources/support/http/resources/sql-detail.html index d1312510eb..57fdee1e49 100644 --- a/src/main/resources/support/http/resources/sql-detail.html +++ b/src/main/resources/support/http/resources/sql-detail.html @@ -104,8 +104,12 @@ - StringReadLength - + ReadStringLength + + + + ReadBytesLength +
@@ -155,7 +159,8 @@ $("#BatchSizeTotal").text(sqlInfo.BatchSizeTotal) $("#BlobOpenCount").text(sqlInfo.BlobOpenCount) $("#ClobOpenCount").text(sqlInfo.ClobOpenCount) - $("#StringReadLength").text(sqlInfo.StringReadLength) + $("#ReadStringLength").text(sqlInfo.ReadStringLength) + $("#ReadBytesLength").text(sqlInfo.ReadBytesLength) }, dataType: "json" }); From d7727a0c02a293903a14d56db174a1c656e995dd Mon Sep 17 00:00:00 2001 From: wenshao Date: Tue, 28 Aug 2012 07:41:35 +0800 Subject: [PATCH 3/3] add sqlStat column, readBytesLength & readStringLength --- .../alibaba/druid/filter/stat/StatFilter.java | 86 ++++++++++++++- .../druid/proxy/jdbc/ResultSetProxy.java | 8 ++ .../druid/proxy/jdbc/ResultSetProxyImpl.java | 37 +++++-- .../com/alibaba/druid/stat/JdbcSqlStat.java | 31 +++++- .../support/http/resources/sql-detail.html | 10 ++ .../filter/StatFilterReadBytesLengthTest.java | 103 ++++++++++++++++++ .../StatFilterReadStringLengthTest.java | 97 +++++++++++++++++ 7 files changed, 362 insertions(+), 10 deletions(-) create mode 100644 src/test/java/com/alibaba/druid/bvt/filter/StatFilterReadBytesLengthTest.java create mode 100644 src/test/java/com/alibaba/druid/bvt/filter/StatFilterReadStringLengthTest.java 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 d90d475a56..facb4864bc 100644 --- a/src/main/java/com/alibaba/druid/filter/stat/StatFilter.java +++ b/src/main/java/com/alibaba/druid/filter/stat/StatFilter.java @@ -16,6 +16,7 @@ package com.alibaba.druid.filter.stat; import java.io.InputStream; +import java.io.Reader; import java.sql.Blob; import java.sql.Clob; import java.sql.NClob; @@ -573,7 +574,18 @@ public class StatFilter extends FilterEventAdapter implements StatFilterMBean { sqlStat.addFetchRowCount(fetchRowCount); long stmtExecuteNano = resultSet.getStatementProxy().getLastExecuteTimeNano(); sqlStat.addResultSetHoldTimeNano(stmtExecuteNano, nanos); - sqlStat.addStringReadLength(resultSet.getReadStringLength()); + if (resultSet.getReadStringLength() > 0) { + sqlStat.addStringReadLength(resultSet.getReadStringLength()); + } + if (resultSet.getReadBytesLength() > 0) { + sqlStat.addReadBytesLength(resultSet.getReadBytesLength()); + } + if (resultSet.getOpenInputStreamCount() > 0) { + sqlStat.addInputStreamOpenCount(resultSet.getOpenInputStreamCount()); + } + if (resultSet.getOpenReaderCount() > 0) { + sqlStat.addReaderOpenCount(resultSet.getOpenReaderCount()); + } } } @@ -960,4 +972,76 @@ public class StatFilter extends FilterEventAdapter implements StatFilterMBean { return value; } + + @Override + public InputStream resultSet_getBinaryStream(FilterChain chain, ResultSetProxy result, int columnIndex) + throws SQLException { + InputStream input = chain.resultSet_getBinaryStream(result, columnIndex); + + if (input != null) { + result.incrementOpenInputStreamCount(); + } + + return input; + } + + @Override + public InputStream resultSet_getBinaryStream(FilterChain chain, ResultSetProxy result, String columnLabel) + throws SQLException { + InputStream input = chain.resultSet_getBinaryStream(result, columnLabel); + + if (input != null) { + result.incrementOpenInputStreamCount(); + } + + return input; + } + + @Override + public InputStream resultSet_getAsciiStream(FilterChain chain, ResultSetProxy result, int columnIndex) + throws SQLException { + InputStream input = chain.resultSet_getAsciiStream(result, columnIndex); + + if (input != null) { + result.incrementOpenInputStreamCount(); + } + + return input; + } + + @Override + public InputStream resultSet_getAsciiStream(FilterChain chain, ResultSetProxy result, String columnLabel) + throws SQLException { + InputStream input = chain.resultSet_getAsciiStream(result, columnLabel); + + if (input != null) { + result.incrementOpenInputStreamCount(); + } + + return input; + } + + @Override + public Reader resultSet_getCharacterStream(FilterChain chain, ResultSetProxy result, int columnIndex) + throws SQLException { + Reader reader = chain.resultSet_getCharacterStream(result, columnIndex); + + if (reader != null) { + result.incrementOpenReaderCount(); + } + + return reader; + } + + @Override + public Reader resultSet_getCharacterStream(FilterChain chain, ResultSetProxy result, String columnLabel) + throws SQLException { + Reader reader = chain.resultSet_getCharacterStream(result, columnLabel); + + if (reader != null) { + result.incrementOpenReaderCount(); + } + + return reader; + } } diff --git a/src/main/java/com/alibaba/druid/proxy/jdbc/ResultSetProxy.java b/src/main/java/com/alibaba/druid/proxy/jdbc/ResultSetProxy.java index 43d5521051..4b4e327d8d 100644 --- a/src/main/java/com/alibaba/druid/proxy/jdbc/ResultSetProxy.java +++ b/src/main/java/com/alibaba/druid/proxy/jdbc/ResultSetProxy.java @@ -51,4 +51,12 @@ public interface ResultSetProxy extends ResultSet, WrapperProxy { void addReadBytesLength(int length); long getReadBytesLength(); + + void incrementOpenInputStreamCount(); + + int getOpenInputStreamCount(); + + void incrementOpenReaderCount(); + + int getOpenReaderCount(); } diff --git a/src/main/java/com/alibaba/druid/proxy/jdbc/ResultSetProxyImpl.java b/src/main/java/com/alibaba/druid/proxy/jdbc/ResultSetProxyImpl.java index 3cc53b278b..ab54e36ada 100644 --- a/src/main/java/com/alibaba/druid/proxy/jdbc/ResultSetProxyImpl.java +++ b/src/main/java/com/alibaba/druid/proxy/jdbc/ResultSetProxyImpl.java @@ -51,14 +51,17 @@ public class ResultSetProxyImpl extends WrapperProxyImpl implements ResultSetPro private final StatementProxy statement; private final String sql; - protected int cursorIndex = 0; - protected int fetchRowCount = 0; + protected int cursorIndex = 0; + protected int fetchRowCount = 0; protected long constructNano; protected final JdbcSqlStat sqlStat; - private int closeCount = 0; + private int closeCount = 0; - private long readStringLength = 0; - private long readBytesLength = 0; + private long readStringLength = 0; + private long readBytesLength = 0; + + private int openInputStreamCount = 0; + private int openReaderCount = 0; public ResultSetProxyImpl(StatementProxy statement, ResultSet resultSet, long id, String sql){ super(resultSet, id); @@ -1090,15 +1093,35 @@ public class ResultSetProxyImpl extends WrapperProxyImpl implements ResultSetPro public long getReadStringLength() { return readStringLength; } - + @Override public void addReadBytesLength(int length) { this.readBytesLength += length; } - + @Override public long getReadBytesLength() { return readBytesLength; } + @Override + public void incrementOpenInputStreamCount() { + openInputStreamCount++; + } + + @Override + public int getOpenInputStreamCount() { + return openInputStreamCount; + } + + @Override + public void incrementOpenReaderCount() { + openReaderCount++; + } + + @Override + public int getOpenReaderCount() { + return openReaderCount; + } + } diff --git a/src/main/java/com/alibaba/druid/stat/JdbcSqlStat.java b/src/main/java/com/alibaba/druid/stat/JdbcSqlStat.java index 2cae8a2e21..2ab364dbd2 100644 --- a/src/main/java/com/alibaba/druid/stat/JdbcSqlStat.java +++ b/src/main/java/com/alibaba/druid/stat/JdbcSqlStat.java @@ -80,6 +80,9 @@ public final class JdbcSqlStat implements JdbcSqlStatMBean { private final AtomicLong readStringLength = new AtomicLong(); private final AtomicLong readBytesLength = new AtomicLong(); + private final AtomicLong inputStreamOpenCount = new AtomicLong(); + private final AtomicLong readerOpenCount = new AtomicLong(); + private final Histogram histogram = new Histogram(new long[] { // // 1, 10, 100, 1000, 10 * 1000, // @@ -230,6 +233,8 @@ public final class JdbcSqlStat implements JdbcSqlStatMBean { clobOpenCount.set(0); readStringLength.set(0); readBytesLength.set(0); + inputStreamOpenCount.set(0); + readerOpenCount.set(0); } public long getConcurrentMax() { @@ -299,9 +304,25 @@ public final class JdbcSqlStat implements JdbcSqlStatMBean { return readBytesLength.get(); } - public void addReadBytesLength(int length) { + public void addReadBytesLength(long length) { this.readBytesLength.addAndGet(length); } + + public long getReaderOpenCount() { + return readerOpenCount.get(); + } + + public void addReaderOpenCount(int count) { + this.readerOpenCount.addAndGet(count); + } + + public long getInputStreamOpenCount() { + return inputStreamOpenCount.get(); + } + + public void addInputStreamOpenCount(int count) { + this.inputStreamOpenCount.addAndGet(count); + } public long getId() { return id; @@ -530,6 +551,8 @@ public final class JdbcSqlStat implements JdbcSqlStatMBean { SimpleType.LONG, // SimpleType.LONG, // SimpleType.LONG, // + SimpleType.LONG, // + SimpleType.LONG, // }; @@ -586,7 +609,9 @@ public final class JdbcSqlStat implements JdbcSqlStatMBean { // 35 - "BlobOpenCount", // "ReadStringLength", // - "ReadBytesLength", + "ReadBytesLength", // + "InputStreamOpenCount", // + "ReaderOpenCount", // // }; @@ -662,6 +687,8 @@ public final class JdbcSqlStat implements JdbcSqlStatMBean { map.put("BlobOpenCount", getBlobOpenCount()); // 35 map.put("ReadStringLength", getReadStringLength()); // 36 map.put("ReadBytesLength", getReadBytesLength()); // 37 + map.put("InputStreamOpenCount", getInputStreamOpenCount()); // 38 + map.put("ReaderOpenCount", getReaderOpenCount()); // 39 return map; } diff --git a/src/main/resources/support/http/resources/sql-detail.html b/src/main/resources/support/http/resources/sql-detail.html index 57fdee1e49..b3ad5478b2 100644 --- a/src/main/resources/support/http/resources/sql-detail.html +++ b/src/main/resources/support/http/resources/sql-detail.html @@ -103,6 +103,14 @@ ClobOpenCount + + ReaderOpenCount + + + + InputStreamOpenCount + + ReadStringLength @@ -159,6 +167,8 @@ $("#BatchSizeTotal").text(sqlInfo.BatchSizeTotal) $("#BlobOpenCount").text(sqlInfo.BlobOpenCount) $("#ClobOpenCount").text(sqlInfo.ClobOpenCount) + $("#InputStreamOpenCount").text(sqlInfo.InputStreamOpenCount) + $("#ReaderOpenCount").text(sqlInfo.ReaderOpenCount) $("#ReadStringLength").text(sqlInfo.ReadStringLength) $("#ReadBytesLength").text(sqlInfo.ReadBytesLength) }, diff --git a/src/test/java/com/alibaba/druid/bvt/filter/StatFilterReadBytesLengthTest.java b/src/test/java/com/alibaba/druid/bvt/filter/StatFilterReadBytesLengthTest.java new file mode 100644 index 0000000000..2322a13f99 --- /dev/null +++ b/src/test/java/com/alibaba/druid/bvt/filter/StatFilterReadBytesLengthTest.java @@ -0,0 +1,103 @@ +package com.alibaba.druid.bvt.filter; + +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; + +import junit.framework.Assert; +import junit.framework.TestCase; + +import com.alibaba.druid.filter.FilterAdapter; +import com.alibaba.druid.filter.FilterChain; +import com.alibaba.druid.pool.DruidDataSource; +import com.alibaba.druid.proxy.jdbc.ResultSetProxy; +import com.alibaba.druid.stat.JdbcSqlStat; +import com.alibaba.druid.util.JdbcUtils; + +public class StatFilterReadBytesLengthTest extends TestCase { + + private DruidDataSource dataSource; + + protected void setUp() throws Exception { + dataSource = new DruidDataSource(); + + dataSource.setUrl("jdbc:mock:xxx"); + dataSource.setFilters("stat"); + dataSource.setTestOnBorrow(false); + dataSource.getProxyFilters().add(new FilterAdapter() { + + @Override + public byte[] resultSet_getBytes(FilterChain chain, ResultSetProxy result, int columnIndex) + throws SQLException { + return new byte[6]; + } + + @Override + public byte[] resultSet_getBytes(FilterChain chain, ResultSetProxy result, String columnIndex) + throws SQLException { + return new byte[7]; + } + }); + + dataSource.init(); + } + + protected void tearDown() throws Exception { + JdbcUtils.close(dataSource); + } + + public void test_stat() throws Exception { + Connection conn = dataSource.getConnection(); + + String sql = "select 'x'"; + PreparedStatement stmt = conn.prepareStatement("select 'x'"); + + JdbcSqlStat sqlStat = dataSource.getDataSourceStat().getSqlStat(sql); + + Assert.assertEquals(0, sqlStat.getReadStringLength()); + Assert.assertEquals(0, sqlStat.getReadBytesLength()); + + ResultSet rs = stmt.executeQuery(); + rs.next(); + rs.getBytes(1); + rs.close(); + stmt.close(); + + conn.close(); + + Assert.assertEquals(0, sqlStat.getReadStringLength()); + Assert.assertEquals(6, sqlStat.getReadBytesLength()); + + sqlStat.reset(); + Assert.assertEquals(0, sqlStat.getReadStringLength()); + Assert.assertEquals(0, sqlStat.getReadBytesLength()); + } + + public void test_stat_1() throws Exception { + Connection conn = dataSource.getConnection(); + + String sql = "select 'x'"; + PreparedStatement stmt = conn.prepareStatement("select 'x'"); + + JdbcSqlStat sqlStat = dataSource.getDataSourceStat().getSqlStat(sql); + + Assert.assertEquals(0, sqlStat.getReadStringLength()); + Assert.assertEquals(0, sqlStat.getReadBytesLength()); + + ResultSet rs = stmt.executeQuery(); + rs.next(); + rs.getBytes("1"); + rs.close(); + stmt.close(); + + conn.close(); + + Assert.assertEquals(0, sqlStat.getReadStringLength()); + Assert.assertEquals(7, sqlStat.getReadBytesLength()); + + sqlStat.reset(); + Assert.assertEquals(0, sqlStat.getReadStringLength()); + Assert.assertEquals(0, sqlStat.getReadBytesLength()); + } +} diff --git a/src/test/java/com/alibaba/druid/bvt/filter/StatFilterReadStringLengthTest.java b/src/test/java/com/alibaba/druid/bvt/filter/StatFilterReadStringLengthTest.java new file mode 100644 index 0000000000..5ff79aab1c --- /dev/null +++ b/src/test/java/com/alibaba/druid/bvt/filter/StatFilterReadStringLengthTest.java @@ -0,0 +1,97 @@ +package com.alibaba.druid.bvt.filter; + +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; + +import junit.framework.Assert; +import junit.framework.TestCase; + +import com.alibaba.druid.filter.FilterAdapter; +import com.alibaba.druid.filter.FilterChain; +import com.alibaba.druid.pool.DruidDataSource; +import com.alibaba.druid.proxy.jdbc.ResultSetProxy; +import com.alibaba.druid.stat.JdbcSqlStat; +import com.alibaba.druid.util.JdbcUtils; + +public class StatFilterReadStringLengthTest extends TestCase { + + private DruidDataSource dataSource; + + protected void setUp() throws Exception { + dataSource = new DruidDataSource(); + + dataSource.setUrl("jdbc:mock:xxx"); + dataSource.setFilters("stat"); + dataSource.setTestOnBorrow(false); + dataSource.getProxyFilters().add(new FilterAdapter() { + + @Override + public String resultSet_getString(FilterChain chain, ResultSetProxy result, int columnIndex) + throws SQLException { + return "123456"; + } + + @Override + public String resultSet_getString(FilterChain chain, ResultSetProxy result, String columnIndex) + throws SQLException { + return "1234567"; + } + }); + + dataSource.init(); + } + + protected void tearDown() throws Exception { + JdbcUtils.close(dataSource); + } + + public void test_stat() throws Exception { + Connection conn = dataSource.getConnection(); + + String sql = "select 'x'"; + PreparedStatement stmt = conn.prepareStatement("select 'x'"); + + JdbcSqlStat sqlStat = dataSource.getDataSourceStat().getSqlStat(sql); + + Assert.assertEquals(0, sqlStat.getReadStringLength()); + + ResultSet rs = stmt.executeQuery(); + rs.next(); + rs.getString(1); + rs.close(); + stmt.close(); + + conn.close(); + + Assert.assertEquals(6, sqlStat.getReadStringLength()); + + sqlStat.reset(); + Assert.assertEquals(0, sqlStat.getReadStringLength()); + } + + public void test_stat_1() throws Exception { + Connection conn = dataSource.getConnection(); + + String sql = "select 'x'"; + PreparedStatement stmt = conn.prepareStatement("select 'x'"); + + JdbcSqlStat sqlStat = dataSource.getDataSourceStat().getSqlStat(sql); + + Assert.assertEquals(0, sqlStat.getReadStringLength()); + + ResultSet rs = stmt.executeQuery(); + rs.next(); + rs.getString("1"); + rs.close(); + stmt.close(); + + conn.close(); + + Assert.assertEquals(7, sqlStat.getReadStringLength()); + + sqlStat.reset(); + Assert.assertEquals(0, sqlStat.getReadStringLength()); + } +}