Skip to content

Commit 3652b1f

Browse files
committed
Provide interface fore connection statistics
1 parent 9c6114d commit 3652b1f

File tree

5 files changed

+297
-1
lines changed

5 files changed

+297
-1
lines changed

README.md

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,38 @@ rslt.next();
9393
System.out.println(rslt.getDate(1));
9494
```
9595

96+
### Get connection statistics
97+
```java
98+
Connection dbConnection = DriverManager.getConnection(
99+
"jdbc:oracle:thin:test/test@//localhost:1521/ORCLPDB1");
100+
101+
ConnectionStats stats = new ConnectionStats(dbConnection);
102+
stats.createSnapshot();
103+
/********************/
104+
/*** DO SOME WORK ***/
105+
/********************/
106+
stats.createSnapshot();
107+
HashMap<String, Long> results = stats.getDelta();
108+
```
109+
110+
### Get connection statistics for a different connection
111+
```java
112+
Connection conn = DriverManager.getConnection(
113+
"jdbc:oracle:thin:test/test@//localhost:1521/ORCLPDB1");
114+
115+
int sessionId = ConnectionInfoFactory.getConnectionInfo(conn).getSid();
116+
117+
ConnectionStats sessionStats = new ConnectionStats(dbConnection);
118+
sessionStats.createSnapshot(sessionId);
119+
/********************/
120+
/*** DO SOME WORK ***/
121+
/*** IN THE OTHER ***/
122+
/***** SESSION ******/
123+
/********************/
124+
sessionStats.createSnapshot(sessionId);
125+
HashMap<String, Long> sessionResults = sessionStats.getDelta();
126+
```
127+
96128
## Database attributes
97129

98130
### Get database information

pom.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
<modelVersion>4.0.0</modelVersion>
33
<groupId>com.gvenzl</groupId>
44
<artifactId>oracleperfutils</artifactId>
5-
<version>0.1.3</version>
5+
<version>0.1.4</version>
66
<name>Oracle Performance Utilities</name>
77
<description>A collection of APIs that interface with various Oracle performance tuning features.</description>
88
<build>
Lines changed: 168 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,168 @@
1+
/*
2+
* author: gvenzl
3+
* created: 23 Dec 2016
4+
*/
5+
6+
package com.gvenzl.stats;
7+
8+
import java.sql.Connection;
9+
import java.sql.PreparedStatement;
10+
import java.sql.ResultSet;
11+
import java.sql.SQLException;
12+
import java.util.ArrayList;
13+
import java.util.HashMap;
14+
import java.util.Map.Entry;
15+
16+
import com.gvenzl.OutOfSequenceException;
17+
18+
/**
19+
* Provides statistic for the database connection.
20+
* @author gvenzl
21+
*
22+
*/
23+
public class ConnectionStats {
24+
25+
private static final int INIT_CAPACITY = 1000;
26+
private Connection myConn;
27+
private HashMap<String, Long> beginStats;
28+
private HashMap<String, Long> endStats;
29+
30+
/**
31+
* Creates a new ConnectionStats object.
32+
* @param conn The connection used to retrieve the statistics
33+
* @throws SQLException Any SQL error during the instantiation
34+
*/
35+
public ConnectionStats(Connection conn) throws SQLException {
36+
37+
if (null == conn || conn.isClosed()) {
38+
throw new SQLException ("No connection to the database");
39+
}
40+
myConn = conn;
41+
}
42+
43+
/**
44+
* Creates a new snapshot for the current connection.
45+
* @throws SQLException Any SQL error during this operation
46+
*/
47+
public void createSnapshot() throws SQLException {
48+
HashMap<String, Long> results = getCurrentStats();
49+
50+
if (null == beginStats) {
51+
beginStats = results;
52+
}
53+
else {
54+
endStats = results;
55+
}
56+
}
57+
58+
/**
59+
* Returns the current statistics for the database connection.
60+
* @return A HashMap of the current statistics
61+
* @throws SQLException Any SQL error during this operation
62+
*/
63+
public HashMap<String, Long> getCurrentStats() throws SQLException {
64+
HashMap<String, Long> results = new HashMap<String, Long>(INIT_CAPACITY);
65+
66+
PreparedStatement stmt = myConn.prepareStatement(
67+
"SELECT n.name, s.value FROM v$mystat s, v$statname n"
68+
+ " WHERE s.statistic# = n.statistic#"
69+
+ " ORDER BY n.name");
70+
ResultSet rslt = stmt.executeQuery();
71+
while (rslt.next()) {
72+
results.put(rslt.getString(1), rslt.getLong(2));
73+
}
74+
stmt.close();
75+
76+
return results;
77+
}
78+
79+
/**
80+
* Creates a new snapshot for the database connection with a given session id.
81+
* @param sessionId The session id (SID) for which to take the snapshot
82+
* @throws SQLException Any SQL error during this operation
83+
*/
84+
public void createSnapshot(int sessionId) throws SQLException {
85+
HashMap<String, Long> results = getCurrentStats(sessionId);
86+
87+
if (null == beginStats) {
88+
beginStats = results;
89+
}
90+
else {
91+
endStats = results;
92+
}
93+
}
94+
95+
/**
96+
* Returns the current statistics for the database connection with the given session id.
97+
* @param sessionId The session id (SID) for which to retrieve the statistics
98+
* @return A HashMap of the current statistics
99+
* @throws SQLException Any SQL error during this operation
100+
*/
101+
public HashMap<String, Long> getCurrentStats(int sessionId) throws SQLException {
102+
HashMap<String, Long> results = new HashMap<String, Long>(INIT_CAPACITY);
103+
104+
PreparedStatement stmt = myConn.prepareStatement(
105+
"SELECT n.name, s.value FROM v$sesstat s, v$statname n"
106+
+ " WHERE s.sid = ? AND s.statistic# = n.statistic#"
107+
+ " ORDER BY n.name");
108+
stmt.setInt(1, sessionId);
109+
ResultSet rslt = stmt.executeQuery();
110+
while (rslt.next()) {
111+
results.put(rslt.getString(1), rslt.getLong(2));
112+
}
113+
stmt.close();
114+
115+
return results;
116+
}
117+
118+
/**
119+
* Returns a delta of the statistics of the connection. Only statistics with a delta are returned.
120+
* @return A HashMap containing all statistics with deltas
121+
* @throws OutOfSequenceException If the begin or end snapshot is out of sequence
122+
*/
123+
public HashMap<String, Long> getDelta() throws OutOfSequenceException {
124+
if (null == beginStats) {
125+
throw new OutOfSequenceException("No begin snapshot available, create begin and end snapshots first!");
126+
}
127+
128+
if (null == endStats) {
129+
throw new OutOfSequenceException("No end snapshot available, create begin snapshot first!");
130+
}
131+
132+
HashMap<String, Long> delta = new HashMap<String, Long>();
133+
134+
for (Entry<String, Long> entry : beginStats.entrySet()) {
135+
String beginKey = entry.getKey();
136+
Long beginValue = entry.getValue();
137+
Long endValue = endStats.get(beginKey);
138+
139+
// Only store delats
140+
long deltaLong = endValue.longValue()-beginValue.longValue();
141+
if (deltaLong != 0) {
142+
delta.put(beginKey, deltaLong);
143+
}
144+
}
145+
146+
beginStats = null;
147+
endStats = null;
148+
149+
return delta;
150+
}
151+
152+
/**
153+
* Returns all statistic names of the database.
154+
* @return A list of all statistic names
155+
* @throws SQLException Any SQL error during this operation
156+
*/
157+
public ArrayList<String> getAllStatisticNames() throws SQLException {
158+
ArrayList<String> stats = new ArrayList<String>(INIT_CAPACITY);
159+
160+
PreparedStatement stmt = myConn.prepareStatement(
161+
"SELECT n.name FROM v$statname n ORDER BY n.name");
162+
ResultSet rslt = stmt.executeQuery();
163+
while (rslt.next()) {
164+
stats.add(rslt.getString(1));
165+
}
166+
return stats;
167+
}
168+
}

src/test/java/com/gvenzl/info/DatabaseInfoTest.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ public class DatabaseInfoTest {
2121
private static final String host = "localhost";
2222
private static final String port = "1521";
2323
private static final String service = "ORCLPDB1";
24+
2425
@Before
2526
public void setup() throws SQLException {
2627
conn = DriverManager.getConnection(
Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
/*
2+
* author: gvenzl
3+
* created: 23 Dec 2016
4+
*/
5+
6+
package com.gvenzl.stats;
7+
8+
import java.sql.Connection;
9+
import java.sql.DriverManager;
10+
import java.sql.SQLException;
11+
12+
import org.junit.Assert;
13+
import org.junit.Before;
14+
import org.junit.Test;
15+
16+
import com.gvenzl.OutOfSequenceException;
17+
import com.gvenzl.info.connection.ConnectionInfoFactory;
18+
19+
public class ConnectionStatsTest {
20+
21+
private Connection conn;
22+
private static final String user = "test";
23+
private static final String password = "test";
24+
private static final String host = "localhost";
25+
private static final String port = "1521";
26+
private static final String service = "ORCLPDB1";
27+
28+
@Before
29+
public void setup() throws SQLException {
30+
conn = DriverManager.getConnection(
31+
"jdbc:oracle:thin:" + user + "/" + password + "@//" + host + ":" + port + "/" + service);
32+
}
33+
34+
@Test
35+
public void test_instantiation() throws SQLException {
36+
System.out.println("test_instantiation()");
37+
new ConnectionStats(conn);
38+
}
39+
40+
@Test
41+
public void test_createSnapshot() throws SQLException {
42+
System.out.println("test_createSnapshot()");
43+
ConnectionStats stats = new ConnectionStats(conn);
44+
stats.createSnapshot();
45+
}
46+
47+
@Test
48+
public void test_createSnapshotDifferentSID() throws SQLException, OutOfSequenceException {
49+
System.out.println("test_createSnapshotDifferentSID()");
50+
Connection testConn = DriverManager.getConnection(
51+
"jdbc:oracle:thin:" + user + "/" + password + "@//" + host + ":" + port + "/" + service);
52+
int sid = ConnectionInfoFactory.getConnectionInfo(testConn).getSid();
53+
54+
ConnectionStats stats = new ConnectionStats(conn);
55+
stats.createSnapshot(sid);
56+
stats.createSnapshot(sid);
57+
Assert.assertNotNull(stats.getDelta());
58+
}
59+
60+
@Test
61+
public void test_getDelta() throws SQLException, OutOfSequenceException {
62+
System.out.println("test_getDelta()");
63+
ConnectionStats stats = new ConnectionStats(conn);
64+
stats.createSnapshot();
65+
stats.createSnapshot();
66+
Assert.assertNotNull(stats.getDelta());
67+
}
68+
69+
@Test
70+
public void test_getAllStatisticNames() throws SQLException {
71+
System.out.println("test_getAllStatisticNames()");
72+
ConnectionStats stats = new ConnectionStats(conn);
73+
Assert.assertNotNull(stats.getAllStatisticNames());
74+
}
75+
76+
@Test
77+
public void test_getCurrentStatistics() throws SQLException {
78+
System.out.println("test_getCurrentStatistics()");
79+
ConnectionStats stats = new ConnectionStats(conn);
80+
Assert.assertNotNull(stats.getCurrentStats());
81+
}
82+
83+
@Test
84+
public void test_getCurrentStatisticsDifferentSID() throws SQLException {
85+
System.out.println("test_getCurrentStatisticsDifferentSID()");
86+
87+
System.out.println("test_createSnapshotDifferentSID()");
88+
Connection testConn = DriverManager.getConnection(
89+
"jdbc:oracle:thin:" + user + "/" + password + "@//" + host + ":" + port + "/" + service);
90+
int sid = ConnectionInfoFactory.getConnectionInfo(testConn).getSid();
91+
92+
ConnectionStats stats = new ConnectionStats(conn);
93+
Assert.assertNotNull(stats.getCurrentStats(sid));
94+
}
95+
}

0 commit comments

Comments
 (0)