Commit 3010ff4f 3010ff4f33c0fb7ab643cd3cd1e5109c727af7af by Christian Gerdes

Forgiving handling of buggy stats from oracle containers under stress

(causes negative deltas and incorrect high delta values).
Also added support to get CPU Usage without Non Idle Wait Time in
percent.
Some optimizations in the code to minimize sql calls.
1 parent e7489513
1 javaw.exe -Dcom.sun.management.jmxremote.ssl=false -cp "wls-10.3.6.0.161018.2/wljmxclient.jar;jconsole.1.8.0_91.jar" sun.tools.jconsole.JConsole "service:jmx:rmi:///jndi/iiop://u30001:17192/weblogic.management.mbeanservers.runtime"
...\ No newline at end of file ...\ No newline at end of file
...@@ -6,3 +6,5 @@ ...@@ -6,3 +6,5 @@
6 /WGet.class 6 /WGet.class
7 /Utils.class 7 /Utils.class
8 /DoubleDelta.class 8 /DoubleDelta.class
9 /CpuTime.class
10 /CpuDelta.class
......
...@@ -58,6 +58,19 @@ class Collector { ...@@ -58,6 +58,19 @@ class Collector {
58 return 0; 58 return 0;
59 } 59 }
60 60
61 public long getDelta(String name) throws Throwable {
62 LongDelta myDelta = null;
63 for(int x = 0; x<list.size() && myDelta == null; x++) {
64 if(name.equals(list.get(x).name)) {
65 myDelta = list.get(x);
66 }
67 }
68 if(myDelta != null)
69 return myDelta.getDelta();
70 else
71 return 0;
72 }
73
61 public double getPerSecValue(String name) throws Throwable { 74 public double getPerSecValue(String name) throws Throwable {
62 LongDelta myDelta = null; 75 LongDelta myDelta = null;
63 for(int x = 0; x<list.size() && myDelta == null; x++) { 76 for(int x = 0; x<list.size() && myDelta == null; x++) {
......
...@@ -9,21 +9,46 @@ class LongDelta { ...@@ -9,21 +9,46 @@ class LongDelta {
9 public Long lastValue = null; 9 public Long lastValue = null;
10 public Timestamp lastFetch = null; 10 public Timestamp lastFetch = null;
11 public Timestamp curFetch = null; 11 public Timestamp curFetch = null;
12 boolean urProt = false; // Under-run protection
13 boolean lastUpdCausedUR = false;
14
15 public LongDelta() {};
16 public LongDelta(boolean UnderrunProtection) { this.urProt = UnderrunProtection; }
12 17
13 public void update(ResultSet rset) throws Throwable{ 18 public void update(ResultSet rset) throws Throwable{
14 update(rset, false); 19 update(rset, 2, false, true);
15 } 20 }
16 public void update(ResultSet rset, boolean convert) throws Throwable{ 21 public void update(ResultSet rset, boolean convert) throws Throwable{
22 update(rset, 2, convert, true);
23 }
24 public void update(ResultSet rset, int pos, boolean convert) throws Throwable{
25 update(rset, pos, convert, true);
26 }
27 public void update(ResultSet rset, int pos, boolean convert, boolean close) throws Throwable{
17 rset.next(); 28 rset.next();
29 long newval = rset.getLong(pos);
30 if(convert) newval = newval/1000;
31 if(urProt) {
32 if(this.curValue != null && this.curValue > newval) {
33 //This would be a negative delta. Ignore this data
34 //System.out.println("Underrunprotection on " + name + " New Val: " + newval + " Old Val: " + this.curValue);
35 lastUpdCausedUR = true;
36 if(close) rset.close();
37 return;
38 }
39 }
18 this.lastFetch = this.curFetch; 40 this.lastFetch = this.curFetch;
19 this.curFetch = rset.getTimestamp(1); 41 this.curFetch = rset.getTimestamp(1);
20 this.lastValue = this.curValue; 42 this.lastValue = this.curValue;
21 if(convert) 43 this.curValue = newval;
22 this.curValue = rset.getLong(2)/1000; 44 lastUpdCausedUR = false;
23 else 45 if(close) rset.close();
24 this.curValue = rset.getLong(2);
25 rset.close();
26 } 46 }
47
48 public boolean didLastUnderRun() {
49 return lastUpdCausedUR;
50 }
51
27 public double getPerSecondValue() throws Throwable { 52 public double getPerSecondValue() throws Throwable {
28 if(this.curValue != null && this.lastValue != null && this.lastFetch != null && this.curFetch != null) { 53 if(this.curValue != null && this.lastValue != null && this.lastFetch != null && this.curFetch != null) {
29 // We have values, calculate the number of gets per second 54 // We have values, calculate the number of gets per second
...@@ -52,4 +77,10 @@ class LongDelta { ...@@ -52,4 +77,10 @@ class LongDelta {
52 } 77 }
53 return 0; 78 return 0;
54 } 79 }
80 public long getDelta() throws Throwable {
81 if(this.lastValue != null && this.curValue != null) {
82 return this.curValue - this.lastValue;
83 }
84 return 0;
85 }
55 } 86 }
...\ No newline at end of file ...\ No newline at end of file
......
...@@ -44,13 +44,35 @@ public class OraMon { ...@@ -44,13 +44,35 @@ public class OraMon {
44 } 44 }
45 45
46 //DB CPU 46 //DB CPU
47 LongDelta cpuTime = new LongDelta(); 47 LongDelta cpuTime = new LongDelta(true);
48 public double getCPUPercent() throws Throwable { 48 LongDelta niwTime = new LongDelta(true);
49 public double getCPUPercent(boolean excludeNonIdleWaitTime) throws Throwable {
49 double perSec = cpuTime.getPerSecondValue(); 50 double perSec = cpuTime.getPerSecondValue();
51 if(excludeNonIdleWaitTime) {
52 double newPerSec = perSec - (niwTime.getPerSecondValue() * 1000);
53 if(newPerSec > 0) perSec = newPerSec; else perSec = 0;
54 }
50 double totSec = numCpus * 1000 * 1000; 55 double totSec = numCpus * 1000 * 1000;
51 double percent = (perSec / totSec) * 100; 56 double percent = (perSec / totSec) * 100;
57 if(percent > 100D) percent=100D;
58 if(percent < 0D) percent=0D;
52 return percent; 59 return percent;
53 } 60 }
61 public double getCPUPercent() throws Throwable {
62 return getCPUPercent(false);
63 }
64 public double getCPUAvailableSeconds() throws Throwable {
65 return cpuTime.getSeconds()*numCpus;
66 }
67 public long getCPURawValue() throws Throwable {
68 return cpuTime.getCurrentValue();
69 }
70 public long getCPURawDiff() {
71 if(cpuTime != null && cpuTime.lastValue != null)
72 return cpuTime.curValue - cpuTime.lastValue;
73 else
74 return 0;
75 }
54 76
55 public double getCPUTimePerSecond() throws Throwable { 77 public double getCPUTimePerSecond() throws Throwable {
56 return cpuTime.getPerSecondValue(); 78 return cpuTime.getPerSecondValue();
...@@ -188,6 +210,7 @@ public class OraMon { ...@@ -188,6 +210,7 @@ public class OraMon {
188 open(); 210 open();
189 } 211 }
190 Statement stmt = conn.createStatement(); 212 Statement stmt = conn.createStatement();
213 Statement scrollStmt = conn.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY);
191 ResultSet rset = null; 214 ResultSet rset = null;
192 215
193 //Get the database name once 216 //Get the database name once
...@@ -205,7 +228,13 @@ public class OraMon { ...@@ -205,7 +228,13 @@ public class OraMon {
205 this.numCpus = (int) colOsStat.getCurrentValue("NUM_CPUS"); 228 this.numCpus = (int) colOsStat.getCurrentValue("NUM_CPUS");
206 229
207 // Get DB CPU use time 230 // Get DB CPU use time
208 cpuTime.update(stmt.executeQuery("select systimestamp, value from V$SYS_TIME_MODEL where stat_name='DB CPU'")); 231 rset = scrollStmt.executeQuery("select systimestamp, s.value as NIWT, t.value as DBCPU from V$SYSSTAT s, V$SYS_TIME_MODEL t where s.name='non-idle wait time' and t.STAT_NAME='DB CPU'");
232 cpuTime.update(rset, 3, false, false);
233 rset.beforeFirst();
234 niwTime.update(rset, 2, false);
235
236 // cpuTime.update(stmt.executeQuery("select systimestamp, value from V$SYS_TIME_MODEL where stat_name='DB CPU'"));
237 // niwTime.update(stmt.executeQuery("select systimestamp, value from V$SYSSTAT where name='non-idle wait time'"));
209 238
210 // Get OS Load 239 // Get OS Load
211 osLoad.update(stmt.executeQuery("select systimestamp, value from V$OSSTAT where stat_name='LOAD'")); 240 osLoad.update(stmt.executeQuery("select systimestamp, value from V$OSSTAT where stat_name='LOAD'"));
......
...@@ -17,51 +17,60 @@ public class TestRunner { ...@@ -17,51 +17,60 @@ public class TestRunner {
17 //ArrayList<OraMon> oraList = new ArrayList<OraMon>(); 17 //ArrayList<OraMon> oraList = new ArrayList<OraMon>();
18 ArrayList<OraMon> oraList = Registry.getList(); 18 ArrayList<OraMon> oraList = Registry.getList();
19 19
20 OraMon mon1 = new OraMon("jdbc:oracle:thin:@//hostname:1521/SID1","system","passw0rd"); 20 OraMon mon1 = new OraMon("jdbc:oracle:thin:@//u03292.kap.rsv.se:1526/AI1K001","dbsnmp","dbsnmp");
21 OraMon mon2 = new OraMon("jdbc:oracle:thin:@//hostname:1521/SID1","system","passw0rd"); 21 OraMon mon2 = new OraMon("jdbc:oracle:thin:@u03292.kap.rsv.se:1526:DB1K09","dbsnmp","dbsnmp");
22 mon1.open(); 22 mon1.open();
23 mon2.open(); 23 mon2.open();
24 oraList.add(mon1); 24 oraList.add(mon1);
25 oraList.add(mon2); 25 oraList.add(mon2);
26 26
27 int times = 10; 27 int times = 100;
28 while(times-- > 0) { 28 while(times-- > 0) {
29 int num = 0;
29 for(OraMon mon : oraList) { 30 for(OraMon mon : oraList) {
31 num++;
30 Long ts1 = System.currentTimeMillis(); 32 Long ts1 = System.currentTimeMillis();
31 mon.getData(); 33 mon.getData();
32 Long time = System.currentTimeMillis() - ts1; 34 Long time = System.currentTimeMillis() - ts1;
33 35
34 System.out.println( 36 System.out.println(
35 "Logical reads:" + mon.getLogicalReadsPerSecond() 37 // "Logical reads:" + mon.getLogicalReadsPerSecond()
36 + " Consistent gets: " + mon.getPerSecondValue("consistent gets") 38 // + " Consistent gets: " + mon.getPerSecondValue("consistent gets")
37 + " Block Gets: " + mon.getPerSecondValue("db block gets") 39 // + " Block Gets: " + mon.getPerSecondValue("db block gets")
38 + " Block Changes: " + mon.getPerSecondValue("db block changes") 40 // + " Block Changes: " + mon.getPerSecondValue("db block changes")
39 + "\n" 41 // + "\n"
40 + "CPUs: " + mon.getNumberOfCPUs() 42 "MON" + num + " CPUs: " + mon.getNumberOfCPUs()
41 + " CPU Time: " + mon.getCPUTimePerSecond() + "ms" 43 + " CPU Time: " + String.format("%1$,.2f", mon.getCPUTimePerSecond()/1000) + "ms/s"
42 + " CPU Usage: " + String.format("%1$,.2f", mon.getCPUPercent()) + "%" 44 + " CPU Usage: " + String.format("%1$,.2f", mon.getCPUPercent()) + "%"
43 + "\n" 45 + " CPU xNIWT: " + String.format("%1$,.2f", mon.getCPUPercent(true)) + "%"
44 + "Cache Hit Ratio: " + String.format("%1$,.2f", mon.getCacheHitRatioPercent()) + "%" 46 + " OS Busy: " + String.format("%1$,.2f", mon.getOsBusyPercent()) + "%"
45 + " Buffer Cache Hit Ratio: " + String.format("%1$,.2f", mon.getBufferCacheHitRatioPercent()) + "%" 47 // + " (Raw: " + mon.getCPURawValue()
46 + "\n" 48 // + " Diff: " + mon.getCPURawDiff()
47 + "Redo size: " + mon.getPerSecondValue("redo size") 49 // + " Available: " + String.format("%1$,.2f", mon.getCPUAvailableSeconds()*1000) + ")"
48 + " Phys Reads: " + mon.getPerSecondValue("physical reads") 50 + " NIWTime: " + String.format("%1$,.2f", mon.niwTime.getPerSecondValue()) + "ms/s"
49 + " Phys Writes: " + mon.getPerSecondValue("physical writes") 51 // + "\n"
50 + " Redo Writes: " + mon.getPerSecondValue("redo writes") 52 // + "Cache Hit Ratio: " + String.format("%1$,.2f", mon.getCacheHitRatioPercent()) + "%"
51 + "\n" 53 // + " Buffer Cache Hit Ratio: " + String.format("%1$,.2f", mon.getBufferCacheHitRatioPercent()) + "%"
52 + "Non Idle Wait: " + mon.getPerSecondValue("non-idle wait time") 54 // + "\n"
53 + " File IO Wait: " + mon.getPerSecondValue("file io wait time") 55 // + "Redo size: " + mon.getPerSecondValue("redo size")
54 + "\n" 56 // + " Phys Reads: " + mon.getPerSecondValue("physical reads")
55 + "Executes: " + mon.getPerSecondValue("execute count") 57 // + " Phys Writes: " + mon.getPerSecondValue("physical writes")
56 + " User calls: " + mon.getPerSecondValue("user calls") 58 // + " Redo Writes: " + mon.getPerSecondValue("redo writes")
57 + " Commits: " + mon.getPerSecondValue("user commits") 59 // + "\n"
58 + " Rollbacks: " + mon.getPerSecondValue("user rollbacks") 60 // + "Non Idle Wait: " + mon.getPerSecondValue("non-idle wait time")
59 + " Parse tot: " + mon.getPerSecondValue("parse count (total)") 61 // + " File IO Wait: " + mon.getPerSecondValue("file io wait time")
60 + " Parse hard: " + mon.getPerSecondValue("parse count (hard)") 62 // + "\n"
61 + "\nTime: " + time + "ms" 63 // + "Executes: " + mon.getPerSecondValue("execute count")
64 // + " User calls: " + mon.getPerSecondValue("user calls")
65 // + " Commits: " + mon.getPerSecondValue("user commits")
66 // + " Rollbacks: " + mon.getPerSecondValue("user rollbacks")
67 // + " Parse tot: " + mon.getPerSecondValue("parse count (total)")
68 // + " Parse hard: " + mon.getPerSecondValue("parse count (hard)")
69 // + "\nTime: " + time + "ms"
62 ); 70 );
63 71
64 } 72 }
73 System.out.println("---------------------------------------------------------------------------------------------------------------");
65 Thread.sleep(15000); 74 Thread.sleep(15000);
66 } 75 }
67 76
......