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
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
......@@ -6,3 +6,5 @@
/WGet.class
/Utils.class
/DoubleDelta.class
/CpuTime.class
/CpuDelta.class
......
......@@ -58,6 +58,19 @@ class Collector {
return 0;
}
public long getDelta(String name) throws Throwable {
LongDelta myDelta = null;
for(int x = 0; x<list.size() && myDelta == null; x++) {
if(name.equals(list.get(x).name)) {
myDelta = list.get(x);
}
}
if(myDelta != null)
return myDelta.getDelta();
else
return 0;
}
public double getPerSecValue(String name) throws Throwable {
LongDelta myDelta = null;
for(int x = 0; x<list.size() && myDelta == null; x++) {
......
......@@ -9,21 +9,46 @@ class LongDelta {
public Long lastValue = null;
public Timestamp lastFetch = null;
public Timestamp curFetch = null;
boolean urProt = false; // Under-run protection
boolean lastUpdCausedUR = false;
public LongDelta() {};
public LongDelta(boolean UnderrunProtection) { this.urProt = UnderrunProtection; }
public void update(ResultSet rset) throws Throwable{
update(rset, false);
update(rset, 2, false, true);
}
public void update(ResultSet rset, boolean convert) throws Throwable{
update(rset, 2, convert, true);
}
public void update(ResultSet rset, int pos, boolean convert) throws Throwable{
update(rset, pos, convert, true);
}
public void update(ResultSet rset, int pos, boolean convert, boolean close) throws Throwable{
rset.next();
long newval = rset.getLong(pos);
if(convert) newval = newval/1000;
if(urProt) {
if(this.curValue != null && this.curValue > newval) {
//This would be a negative delta. Ignore this data
//System.out.println("Underrunprotection on " + name + " New Val: " + newval + " Old Val: " + this.curValue);
lastUpdCausedUR = true;
if(close) rset.close();
return;
}
}
this.lastFetch = this.curFetch;
this.curFetch = rset.getTimestamp(1);
this.lastValue = this.curValue;
if(convert)
this.curValue = rset.getLong(2)/1000;
else
this.curValue = rset.getLong(2);
rset.close();
this.curValue = newval;
lastUpdCausedUR = false;
if(close) rset.close();
}
public boolean didLastUnderRun() {
return lastUpdCausedUR;
}
public double getPerSecondValue() throws Throwable {
if(this.curValue != null && this.lastValue != null && this.lastFetch != null && this.curFetch != null) {
// We have values, calculate the number of gets per second
......@@ -52,4 +77,10 @@ class LongDelta {
}
return 0;
}
public long getDelta() throws Throwable {
if(this.lastValue != null && this.curValue != null) {
return this.curValue - this.lastValue;
}
return 0;
}
}
\ No newline at end of file
......
......@@ -44,13 +44,35 @@ public class OraMon {
}
//DB CPU
LongDelta cpuTime = new LongDelta();
public double getCPUPercent() throws Throwable {
LongDelta cpuTime = new LongDelta(true);
LongDelta niwTime = new LongDelta(true);
public double getCPUPercent(boolean excludeNonIdleWaitTime) throws Throwable {
double perSec = cpuTime.getPerSecondValue();
if(excludeNonIdleWaitTime) {
double newPerSec = perSec - (niwTime.getPerSecondValue() * 1000);
if(newPerSec > 0) perSec = newPerSec; else perSec = 0;
}
double totSec = numCpus * 1000 * 1000;
double percent = (perSec / totSec) * 100;
if(percent > 100D) percent=100D;
if(percent < 0D) percent=0D;
return percent;
}
public double getCPUPercent() throws Throwable {
return getCPUPercent(false);
}
public double getCPUAvailableSeconds() throws Throwable {
return cpuTime.getSeconds()*numCpus;
}
public long getCPURawValue() throws Throwable {
return cpuTime.getCurrentValue();
}
public long getCPURawDiff() {
if(cpuTime != null && cpuTime.lastValue != null)
return cpuTime.curValue - cpuTime.lastValue;
else
return 0;
}
public double getCPUTimePerSecond() throws Throwable {
return cpuTime.getPerSecondValue();
......@@ -188,6 +210,7 @@ public class OraMon {
open();
}
Statement stmt = conn.createStatement();
Statement scrollStmt = conn.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY);
ResultSet rset = null;
//Get the database name once
......@@ -205,7 +228,13 @@ public class OraMon {
this.numCpus = (int) colOsStat.getCurrentValue("NUM_CPUS");
// Get DB CPU use time
cpuTime.update(stmt.executeQuery("select systimestamp, value from V$SYS_TIME_MODEL where stat_name='DB CPU'"));
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'");
cpuTime.update(rset, 3, false, false);
rset.beforeFirst();
niwTime.update(rset, 2, false);
// cpuTime.update(stmt.executeQuery("select systimestamp, value from V$SYS_TIME_MODEL where stat_name='DB CPU'"));
// niwTime.update(stmt.executeQuery("select systimestamp, value from V$SYSSTAT where name='non-idle wait time'"));
// Get OS Load
osLoad.update(stmt.executeQuery("select systimestamp, value from V$OSSTAT where stat_name='LOAD'"));
......
......@@ -17,51 +17,60 @@ public class TestRunner {
//ArrayList<OraMon> oraList = new ArrayList<OraMon>();
ArrayList<OraMon> oraList = Registry.getList();
OraMon mon1 = new OraMon("jdbc:oracle:thin:@//hostname:1521/SID1","system","passw0rd");
OraMon mon2 = new OraMon("jdbc:oracle:thin:@//hostname:1521/SID1","system","passw0rd");
OraMon mon1 = new OraMon("jdbc:oracle:thin:@//u03292.kap.rsv.se:1526/AI1K001","dbsnmp","dbsnmp");
OraMon mon2 = new OraMon("jdbc:oracle:thin:@u03292.kap.rsv.se:1526:DB1K09","dbsnmp","dbsnmp");
mon1.open();
mon2.open();
oraList.add(mon1);
oraList.add(mon2);
int times = 10;
int times = 100;
while(times-- > 0) {
int num = 0;
for(OraMon mon : oraList) {
num++;
Long ts1 = System.currentTimeMillis();
mon.getData();
Long time = System.currentTimeMillis() - ts1;
System.out.println(
"Logical reads:" + mon.getLogicalReadsPerSecond()
+ " Consistent gets: " + mon.getPerSecondValue("consistent gets")
+ " Block Gets: " + mon.getPerSecondValue("db block gets")
+ " Block Changes: " + mon.getPerSecondValue("db block changes")
+ "\n"
+ "CPUs: " + mon.getNumberOfCPUs()
+ " CPU Time: " + mon.getCPUTimePerSecond() + "ms"
// "Logical reads:" + mon.getLogicalReadsPerSecond()
// + " Consistent gets: " + mon.getPerSecondValue("consistent gets")
// + " Block Gets: " + mon.getPerSecondValue("db block gets")
// + " Block Changes: " + mon.getPerSecondValue("db block changes")
// + "\n"
"MON" + num + " CPUs: " + mon.getNumberOfCPUs()
+ " CPU Time: " + String.format("%1$,.2f", mon.getCPUTimePerSecond()/1000) + "ms/s"
+ " CPU Usage: " + String.format("%1$,.2f", mon.getCPUPercent()) + "%"
+ "\n"
+ "Cache Hit Ratio: " + String.format("%1$,.2f", mon.getCacheHitRatioPercent()) + "%"
+ " Buffer Cache Hit Ratio: " + String.format("%1$,.2f", mon.getBufferCacheHitRatioPercent()) + "%"
+ "\n"
+ "Redo size: " + mon.getPerSecondValue("redo size")
+ " Phys Reads: " + mon.getPerSecondValue("physical reads")
+ " Phys Writes: " + mon.getPerSecondValue("physical writes")
+ " Redo Writes: " + mon.getPerSecondValue("redo writes")
+ "\n"
+ "Non Idle Wait: " + mon.getPerSecondValue("non-idle wait time")
+ " File IO Wait: " + mon.getPerSecondValue("file io wait time")
+ "\n"
+ "Executes: " + mon.getPerSecondValue("execute count")
+ " User calls: " + mon.getPerSecondValue("user calls")
+ " Commits: " + mon.getPerSecondValue("user commits")
+ " Rollbacks: " + mon.getPerSecondValue("user rollbacks")
+ " Parse tot: " + mon.getPerSecondValue("parse count (total)")
+ " Parse hard: " + mon.getPerSecondValue("parse count (hard)")
+ "\nTime: " + time + "ms"
+ " CPU xNIWT: " + String.format("%1$,.2f", mon.getCPUPercent(true)) + "%"
+ " OS Busy: " + String.format("%1$,.2f", mon.getOsBusyPercent()) + "%"
// + " (Raw: " + mon.getCPURawValue()
// + " Diff: " + mon.getCPURawDiff()
// + " Available: " + String.format("%1$,.2f", mon.getCPUAvailableSeconds()*1000) + ")"
+ " NIWTime: " + String.format("%1$,.2f", mon.niwTime.getPerSecondValue()) + "ms/s"
// + "\n"
// + "Cache Hit Ratio: " + String.format("%1$,.2f", mon.getCacheHitRatioPercent()) + "%"
// + " Buffer Cache Hit Ratio: " + String.format("%1$,.2f", mon.getBufferCacheHitRatioPercent()) + "%"
// + "\n"
// + "Redo size: " + mon.getPerSecondValue("redo size")
// + " Phys Reads: " + mon.getPerSecondValue("physical reads")
// + " Phys Writes: " + mon.getPerSecondValue("physical writes")
// + " Redo Writes: " + mon.getPerSecondValue("redo writes")
// + "\n"
// + "Non Idle Wait: " + mon.getPerSecondValue("non-idle wait time")
// + " File IO Wait: " + mon.getPerSecondValue("file io wait time")
// + "\n"
// + "Executes: " + mon.getPerSecondValue("execute count")
// + " User calls: " + mon.getPerSecondValue("user calls")
// + " Commits: " + mon.getPerSecondValue("user commits")
// + " Rollbacks: " + mon.getPerSecondValue("user rollbacks")
// + " Parse tot: " + mon.getPerSecondValue("parse count (total)")
// + " Parse hard: " + mon.getPerSecondValue("parse count (hard)")
// + "\nTime: " + time + "ms"
);
}
System.out.println("---------------------------------------------------------------------------------------------------------------");
Thread.sleep(15000);
}
......