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..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,6 +574,18 @@ public class StatFilter extends FilterEventAdapter implements StatFilterMBean {
sqlStat.addFetchRowCount(fetchRowCount);
long stmtExecuteNano = resultSet.getStatementProxy().getLastExecuteTimeNano();
sqlStat.addResultSetHoldTimeNano(stmtExecuteNano, nanos);
+ 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());
+ }
}
}
@@ -708,26 +721,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;
}
@@ -761,10 +774,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 +790,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 +805,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 +821,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;
@@ -825,7 +838,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);
}
@@ -881,7 +894,7 @@ public class StatFilter extends FilterEventAdapter implements StatFilterMBean {
return obj;
}
-
+
private void blobOpenAfter(JdbcDataSourceStat dataSourceStat, ResultSetProxy rs, Blob blob) {
blobOpenAfter(dataSourceStat, rs.getStatementProxy(), blob);
}
@@ -892,7 +905,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) {
@@ -915,4 +928,120 @@ 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;
+ }
+
+ @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 f6a6ff7ef2..4b4e327d8d 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,20 @@ public interface ResultSetProxy extends ResultSet, WrapperProxy {
void setConstructNano();
int getCloseCount();
+
+ void addReadStringLength(int length);
+
+ long getReadStringLength();
+
+ 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 45017f8596..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,11 +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 int openInputStreamCount = 0;
+ private int openReaderCount = 0;
public ResultSetProxyImpl(StatementProxy statement, ResultSet resultSet, long id, String sql){
super(resultSet, id);
@@ -1078,4 +1084,44 @@ public class ResultSetProxyImpl extends WrapperProxyImpl implements ResultSetPro
return closeCount;
}
+ @Override
+ public void addReadStringLength(int length) {
+ this.readStringLength += length;
+ }
+
+ @Override
+ 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 01770643e5..2ab364dbd2 100644
--- a/src/main/java/com/alibaba/druid/stat/JdbcSqlStat.java
+++ b/src/main/java/com/alibaba/druid/stat/JdbcSqlStat.java
@@ -77,6 +77,11 @@ public final class JdbcSqlStat implements JdbcSqlStatMBean {
private final AtomicLong clobOpenCount = new AtomicLong();
private final AtomicLong blobOpenCount = new AtomicLong();
+ 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[] { //
//
@@ -226,6 +231,10 @@ public final class JdbcSqlStat implements JdbcSqlStatMBean {
blobOpenCount.set(0);
clobOpenCount.set(0);
+ readStringLength.set(0);
+ readBytesLength.set(0);
+ inputStreamOpenCount.set(0);
+ readerOpenCount.set(0);
}
public long getConcurrentMax() {
@@ -274,15 +283,47 @@ public final class JdbcSqlStat implements JdbcSqlStatMBean {
public void incrementClobOpenCount() {
clobOpenCount.incrementAndGet();
}
-
+
public long getBlobOpenCount() {
return blobOpenCount.get();
}
-
+
public void incrementBlobOpenCount() {
blobOpenCount.incrementAndGet();
}
+ public long getReadStringLength() {
+ return readStringLength.get();
+ }
+
+ public void addStringReadLength(long length) {
+ this.readStringLength.addAndGet(length);
+ }
+
+ public long getReadBytesLength() {
+ return readBytesLength.get();
+ }
+
+ 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;
}
@@ -505,9 +546,13 @@ public final class JdbcSqlStat implements JdbcSqlStatMBean {
SimpleType.LONG, //
SimpleType.LONG, //
SimpleType.LONG, //
-
+
// 35 -
SimpleType.LONG, //
+ SimpleType.LONG, //
+ SimpleType.LONG, //
+ SimpleType.LONG, //
+ SimpleType.LONG, //
};
@@ -560,9 +605,13 @@ public final class JdbcSqlStat implements JdbcSqlStatMBean {
"EffectedRowCountMax", //
"FetchRowCountMax", //
"ClobOpenCount",
-
+
// 35 -
- "BlobOpenCount",
+ "BlobOpenCount", //
+ "ReadStringLength", //
+ "ReadBytesLength", //
+ "InputStreamOpenCount", //
+ "ReaderOpenCount", //
//
};
@@ -634,8 +683,12 @@ 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("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 8cfaf38f1d..b3ad5478b2 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 @@
-
| BatchSizeMax | @@ -95,6 +95,30 @@BatchSizeTotal | |
| BlobOpenCount | ++ | |
| ClobOpenCount | ++ | |
| ReaderOpenCount | ++ | |
| InputStreamOpenCount | ++ | |
| ReadStringLength | ++ | |
| ReadBytesLength | ++ |