Ökat nogrannheten överlag genom att använda doubles istället för long
och undvika avrundningar i både LongDelta, Collector och OraMon. Skapat en ny klass DoubleDelta som kan hantera värden från Oracle med decimaler, behövdes för att mäta LOAD från OSSTAT. Testat med både piloop och cpuloop i oracle sql (som tar en hel cpu) och mätvärden ser ut att stämma bra.
Showing
10 changed files
with
92 additions
and
22 deletions
No preview for this file type
No preview for this file type
... | @@ -76,9 +76,9 @@ public class OraMonRESTgetMetrics extends HttpServlet { | ... | @@ -76,9 +76,9 @@ public class OraMonRESTgetMetrics extends HttpServlet { |
76 | for (OraMon item : list) { | 76 | for (OraMon item : list) { |
77 | if (list.size() > 1) aStr = " " + item.getDBName(); | 77 | if (list.size() > 1) aStr = " " + item.getDBName(); |
78 | sb.append("{\"name\":\"Cpus (#)" + aStr + "\",\"value\":" + item.getNumberOfCPUs() + "}"); | 78 | sb.append("{\"name\":\"Cpus (#)" + aStr + "\",\"value\":" + item.getNumberOfCPUs() + "}"); |
79 | sb.append(",{\"name\":\"Cpu Time (ms/s)" + aStr + "\",\"value\":" + item.getCPUTimePerSecond() + "}"); | 79 | sb.append(",{\"name\":\"Cpu Time (us/s)" + aStr + "\",\"value\":" + item.getCPUTimePerSecond() + "}"); |
80 | sb.append(",{\"name\":\"Cpu Usage (%)" + aStr + "\",\"value\":" + item.getCPUPercent() + "}"); | 80 | sb.append(",{\"name\":\"Cpu Usage (%)" + aStr + "\",\"value\":" + item.getCPUPercent() + "}"); |
81 | sb.append(",{\"name\":\"OS Cpu Usage (%)" + aStr + "\",\"value\":" + item.getOsBusyPercent() + "}"); | 81 | sb.append(",{\"name\":\"OS Busy (%)" + aStr + "\",\"value\":" + item.getOsBusyPercent() + "}"); |
82 | sb.append(",{\"name\":\"OS Load (#)" + aStr + "\",\"value\":" + item.getOsLoad() + "}"); | 82 | sb.append(",{\"name\":\"OS Load (#)" + aStr + "\",\"value\":" + item.getOsLoad() + "}"); |
83 | sb.append(",{\"name\":\"OS Load per Cpu (#)" + aStr + "\",\"value\":" + item.getOsLoadPerCPU() + "}"); | 83 | sb.append(",{\"name\":\"OS Load per Cpu (#)" + aStr + "\",\"value\":" + item.getOsLoadPerCPU() + "}"); |
84 | sb.append(",{\"name\":\"Logical Reads (#/s)" + aStr + "\",\"value\":" + item.getLogicalReadsPerSecond() + "}"); | 84 | sb.append(",{\"name\":\"Logical Reads (#/s)" + aStr + "\",\"value\":" + item.getLogicalReadsPerSecond() + "}"); | ... | ... |
... | @@ -3,6 +3,6 @@ | ... | @@ -3,6 +3,6 @@ |
3 | <classpathentry kind="src" path=""/> | 3 | <classpathentry kind="src" path=""/> |
4 | <classpathentry exported="true" kind="lib" path="lib/ojdbc6.jar"/> | 4 | <classpathentry exported="true" kind="lib" path="lib/ojdbc6.jar"/> |
5 | <classpathentry exported="true" kind="lib" path="lib/ojdbc5.jar"/> | 5 | <classpathentry exported="true" kind="lib" path="lib/ojdbc5.jar"/> |
6 | <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.6"/> | 6 | <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/> |
7 | <classpathentry kind="output" path=""/> | 7 | <classpathentry kind="output" path=""/> |
8 | </classpath> | 8 | </classpath> | ... | ... |
... | @@ -48,7 +48,7 @@ class Collector { | ... | @@ -48,7 +48,7 @@ class Collector { |
48 | return 0; | 48 | return 0; |
49 | } | 49 | } |
50 | 50 | ||
51 | public long getPerSecValue(String name) throws Throwable { | 51 | public double getPerSecValue(String name) throws Throwable { |
52 | LongDelta myDelta = null; | 52 | LongDelta myDelta = null; |
53 | for(int x = 0; x<list.size() && myDelta == null; x++) { | 53 | for(int x = 0; x<list.size() && myDelta == null; x++) { |
54 | if(name.equals(list.get(x).name)) { | 54 | if(name.equals(list.get(x).name)) { | ... | ... |
LILOM Library/se/lil/om/DoubleDelta.java
0 → 100644
1 | package se.lil.om; | ||
2 | |||
3 | import java.sql.ResultSet; | ||
4 | import java.sql.Timestamp; | ||
5 | |||
6 | public class DoubleDelta { | ||
7 | public String name = null; | ||
8 | public Double curValue = null; | ||
9 | public Double lastValue = null; | ||
10 | public Timestamp lastFetch = null; | ||
11 | public Timestamp curFetch = null; | ||
12 | |||
13 | public void update(ResultSet rset) throws Throwable{ | ||
14 | update(rset, false); | ||
15 | } | ||
16 | public void update(ResultSet rset, boolean convert) throws Throwable{ | ||
17 | rset.next(); | ||
18 | this.lastFetch = this.curFetch; | ||
19 | this.curFetch = rset.getTimestamp(1); | ||
20 | this.lastValue = this.curValue; | ||
21 | if(convert) | ||
22 | this.curValue = rset.getDouble(2)/1000; | ||
23 | else | ||
24 | this.curValue = rset.getDouble(2); | ||
25 | rset.close(); | ||
26 | } | ||
27 | public double getPerSecondValue() throws Throwable { | ||
28 | if(this.curValue != null && this.lastValue != null && this.lastFetch != null && this.curFetch != null) { | ||
29 | // We have values, calculate the number of gets per second | ||
30 | double numMilliSeconds = this.curFetch.getTime() - this.lastFetch.getTime(); | ||
31 | double delta = this.curValue - this.lastValue; | ||
32 | double perMilli = delta/numMilliSeconds; | ||
33 | return perMilli * 1000; | ||
34 | } else { | ||
35 | return 0; | ||
36 | } | ||
37 | } | ||
38 | public double getCurrentValue() throws Throwable { | ||
39 | if(this.curValue != null) return this.curValue; | ||
40 | else return 0; | ||
41 | } | ||
42 | public double getSeconds() throws Throwable { | ||
43 | if(this.lastFetch != null && this.curFetch != null) { | ||
44 | double numSeconds = this.curFetch.getTime() - this.lastFetch.getTime(); | ||
45 | return numSeconds/1000; | ||
46 | } | ||
47 | return 0; | ||
48 | } | ||
49 | public long getMilliSeconds() throws Throwable { | ||
50 | if(this.lastFetch != null && this.curFetch != null) { | ||
51 | return this.curFetch.getTime() - this.lastFetch.getTime(); | ||
52 | } | ||
53 | return 0; | ||
54 | } | ||
55 | } |
... | @@ -24,12 +24,13 @@ class LongDelta { | ... | @@ -24,12 +24,13 @@ class LongDelta { |
24 | this.curValue = rset.getLong(2); | 24 | this.curValue = rset.getLong(2); |
25 | rset.close(); | 25 | rset.close(); |
26 | } | 26 | } |
27 | public long getPerSecondValue() throws Throwable { | 27 | public double getPerSecondValue() throws Throwable { |
28 | if(this.curValue != null && this.lastValue != null && this.lastFetch != null && this.curFetch != null) { | 28 | if(this.curValue != null && this.lastValue != null && this.lastFetch != null && this.curFetch != null) { |
29 | // We have values, calculate the number of gets per second | 29 | // We have values, calculate the number of gets per second |
30 | long numSeconds = (this.curFetch.getTime() - this.lastFetch.getTime()) / 1000; | 30 | double numMilliSeconds = this.curFetch.getTime() - this.lastFetch.getTime(); |
31 | long delta = this.curValue - this.lastValue; | 31 | double delta = this.curValue - this.lastValue; |
32 | return delta/numSeconds; | 32 | double perMilli = delta/numMilliSeconds; |
33 | return perMilli * 1000; | ||
33 | } else { | 34 | } else { |
34 | return 0; | 35 | return 0; |
35 | } | 36 | } |
... | @@ -38,10 +39,16 @@ class LongDelta { | ... | @@ -38,10 +39,16 @@ class LongDelta { |
38 | if(this.curValue != null) return this.curValue; | 39 | if(this.curValue != null) return this.curValue; |
39 | else return 0; | 40 | else return 0; |
40 | } | 41 | } |
41 | public long getSeconds() throws Throwable { | 42 | public double getSeconds() throws Throwable { |
42 | if(this.lastFetch != null && this.curFetch != null) { | 43 | if(this.lastFetch != null && this.curFetch != null) { |
43 | long numSeconds = (this.curFetch.getTime() - this.lastFetch.getTime()) / 1000; | 44 | double numSeconds = this.curFetch.getTime() - this.lastFetch.getTime(); |
44 | return numSeconds; | 45 | return numSeconds/1000; |
46 | } | ||
47 | return 0; | ||
48 | } | ||
49 | public long getMilliSeconds() throws Throwable { | ||
50 | if(this.lastFetch != null && this.curFetch != null) { | ||
51 | return this.curFetch.getTime() - this.lastFetch.getTime(); | ||
45 | } | 52 | } |
46 | return 0; | 53 | return 0; |
47 | } | 54 | } | ... | ... |
... | @@ -47,20 +47,20 @@ public class OraMon { | ... | @@ -47,20 +47,20 @@ public class OraMon { |
47 | LongDelta cpuTime = new LongDelta(); | 47 | LongDelta cpuTime = new LongDelta(); |
48 | public double getCPUPercent() throws Throwable { | 48 | public double getCPUPercent() throws Throwable { |
49 | double perSec = cpuTime.getPerSecondValue(); | 49 | double perSec = cpuTime.getPerSecondValue(); |
50 | double totSec = numCpus * 1000; | 50 | double totSec = numCpus * 1000 * 1000; |
51 | double percent = (perSec / totSec) * 100; | 51 | double percent = (perSec / totSec) * 100; |
52 | return percent; | 52 | return percent; |
53 | } | 53 | } |
54 | 54 | ||
55 | public long getCPUTimePerSecond() throws Throwable { | 55 | public double getCPUTimePerSecond() throws Throwable { |
56 | return cpuTime.getPerSecondValue(); | 56 | return cpuTime.getPerSecondValue(); |
57 | } | 57 | } |
58 | 58 | ||
59 | public long getPerSecondValue(String name) throws Throwable { | 59 | public double getPerSecondValue(String name) throws Throwable { |
60 | return getPerSecondValue(name, SYSSTAT); | 60 | return getPerSecondValue(name, SYSSTAT); |
61 | } | 61 | } |
62 | 62 | ||
63 | public long getPerSecondValue(String name, int table) throws Throwable { | 63 | public double getPerSecondValue(String name, int table) throws Throwable { |
64 | switch (table) { | 64 | switch (table) { |
65 | case OSSTAT: | 65 | case OSSTAT: |
66 | return colOsStat.getPerSecValue(name); | 66 | return colOsStat.getPerSecValue(name); |
... | @@ -78,16 +78,19 @@ public class OraMon { | ... | @@ -78,16 +78,19 @@ public class OraMon { |
78 | public double getOsBusyPercent() throws Throwable { | 78 | public double getOsBusyPercent() throws Throwable { |
79 | double idle = getPerSecondValue("IDLE_TIME", OSSTAT); | 79 | double idle = getPerSecondValue("IDLE_TIME", OSSTAT); |
80 | double busy = getPerSecondValue("BUSY_TIME", OSSTAT); | 80 | double busy = getPerSecondValue("BUSY_TIME", OSSTAT); |
81 | return busy/(busy+idle); | 81 | return 100*(busy/(busy+idle)); |
82 | } | 82 | } |
83 | 83 | ||
84 | public long getOsLoad() throws Throwable { | 84 | // OS LOAD |
85 | return colOsStat.getCurrentValue("LOAD"); | 85 | DoubleDelta osLoad = new DoubleDelta(); |
86 | |||
87 | public double getOsLoad() throws Throwable { | ||
88 | return osLoad.getCurrentValue(); | ||
86 | } | 89 | } |
87 | 90 | ||
88 | public double getOsLoadPerCPU() throws Throwable { | 91 | public double getOsLoadPerCPU() throws Throwable { |
89 | double num = this.numCpus; | 92 | double num = this.numCpus; |
90 | double load = colOsStat.getCurrentValue("LOAD"); | 93 | double load = getOsLoad(); |
91 | return load / num; | 94 | return load / num; |
92 | } | 95 | } |
93 | 96 | ||
... | @@ -119,7 +122,7 @@ public class OraMon { | ... | @@ -119,7 +122,7 @@ public class OraMon { |
119 | return cacheHitRatio * 100; | 122 | return cacheHitRatio * 100; |
120 | } | 123 | } |
121 | 124 | ||
122 | public long getLogicalReadsPerSecond() throws Throwable { | 125 | public double getLogicalReadsPerSecond() throws Throwable { |
123 | return getPerSecondValue("consistent gets") + getPerSecondValue("db block gets"); | 126 | return getPerSecondValue("consistent gets") + getPerSecondValue("db block gets"); |
124 | } | 127 | } |
125 | 128 | ||
... | @@ -187,7 +190,11 @@ public class OraMon { | ... | @@ -187,7 +190,11 @@ public class OraMon { |
187 | //Set numCpus | 190 | //Set numCpus |
188 | this.numCpus = (int) colOsStat.getCurrentValue("NUM_CPUS"); | 191 | this.numCpus = (int) colOsStat.getCurrentValue("NUM_CPUS"); |
189 | 192 | ||
190 | cpuTime.update(stmt.executeQuery("select systimestamp, value from V$SYS_TIME_MODEL where stat_name='DB CPU'"), true); | 193 | // Get DB CPU use time |
194 | cpuTime.update(stmt.executeQuery("select systimestamp, value from V$SYS_TIME_MODEL where stat_name='DB CPU'")); | ||
195 | |||
196 | // Get OS Load | ||
197 | osLoad.update(stmt.executeQuery("select systimestamp, value from V$OSSTAT where stat_name='LOAD'")); | ||
191 | 198 | ||
192 | //Get the entire V_$SYSSTAT table from DB | 199 | //Get the entire V_$SYSSTAT table from DB |
193 | colSysStat.update(stmt.executeQuery("select systimestamp, name, value from V$SYSSTAT")); | 200 | colSysStat.update(stmt.executeQuery("select systimestamp, name, value from V$SYSSTAT")); | ... | ... |
-
Please register or sign in to post a comment