Mercurial > hg > release > thermostat-0.15
changeset 266:aa3fb04ae01f
Avoid negative value results when computing cpu usage
Reviewed-by: vanaltj
Review-thread: http://icedtea.classpath.org/pipermail/thermostat/2012-April/001086.html
author | Omair Majid <omajid@redhat.com> |
---|---|
date | Thu, 26 Apr 2012 13:32:33 -0400 |
parents | 70acf0d10ec2 |
children | 7d5c9fdb7305 |
files | agent/src/main/java/com/redhat/thermostat/backend/system/ProcessStatusInfoBuilder.java agent/src/main/java/com/redhat/thermostat/backend/system/SystemBackend.java agent/src/main/java/com/redhat/thermostat/backend/system/VmCpuStatBuilder.java agent/src/test/java/com/redhat/thermostat/backend/system/VmCpuStatBuilderTest.java |
diffstat | 4 files changed, 37 insertions(+), 8 deletions(-) [+] |
line wrap: on
line diff
--- a/agent/src/main/java/com/redhat/thermostat/backend/system/ProcessStatusInfoBuilder.java Thu Apr 26 13:29:37 2012 -0400 +++ b/agent/src/main/java/com/redhat/thermostat/backend/system/ProcessStatusInfoBuilder.java Thu Apr 26 13:32:33 2012 -0400 @@ -68,7 +68,7 @@ logger.log(Level.WARNING, "unable to read stat info for " + pid); } - return new ProcessStatusInfo(-1, -1, -1); + return null; } private ProcessStatusInfo build(Reader r) throws IOException {
--- a/agent/src/main/java/com/redhat/thermostat/backend/system/SystemBackend.java Thu Apr 26 13:29:37 2012 -0400 +++ b/agent/src/main/java/com/redhat/thermostat/backend/system/SystemBackend.java Thu Apr 26 13:32:33 2012 -0400 @@ -67,6 +67,7 @@ import com.redhat.thermostat.common.dao.VmInfoDAO; import com.redhat.thermostat.common.dao.VmMemoryStatDAO; import com.redhat.thermostat.common.model.NetworkInterfaceInfo; +import com.redhat.thermostat.common.model.VmCpuStat; import com.redhat.thermostat.common.storage.Category; import com.redhat.thermostat.common.utils.LoggingUtils; @@ -161,7 +162,10 @@ for (Integer pid : pidsToMonitor) { if (vmCpuBuilder.knowsAbout(pid)) { - vmCpuStats.putVmCpuStat(vmCpuBuilder.build(pid)); + VmCpuStat dataBuilt = vmCpuBuilder.build(pid); + if (dataBuilt != null) { + vmCpuStats.putVmCpuStat(dataBuilt); + } } else { vmCpuBuilder.learnAbout(pid); }
--- a/agent/src/main/java/com/redhat/thermostat/backend/system/VmCpuStatBuilder.java Thu Apr 26 13:29:37 2012 -0400 +++ b/agent/src/main/java/com/redhat/thermostat/backend/system/VmCpuStatBuilder.java Thu Apr 26 13:32:33 2012 -0400 @@ -67,12 +67,9 @@ } /** - * To build the stat, this method needs to be called repeatedly. The first - * time (in the entire run time) it is called, the result will most be - * useless. The second (and later calls) should produce usable results. - * - * @param pid - * @return + * @param pid the process id + * @return an object representing the cpu usage of the process, or null if + * the information can not be found. */ public synchronized VmCpuStat build(Integer pid) { if (!lastProcessTicks.containsKey(pid) || !lastProcessTickTime.containsKey(pid)) { @@ -80,6 +77,9 @@ } ProcessStatusInfo info = statusBuilder.build(pid); + if (info == null) { + return null; + } long miliTime = clock.getRealTimeMillis(); long time = clock.getMonotonicTimeNanos(); long programTicks = (info.getKernelTime() + info.getUserTime()); @@ -113,6 +113,9 @@ public synchronized void learnAbout(int pid) { long time = clock.getMonotonicTimeNanos(); ProcessStatusInfo info = statusBuilder.build(pid); + if (info == null) { + logger.log(Level.WARNING, "can not learn about pid " + pid + " : statusBuilder returned null"); + } lastProcessTickTime.put(pid, time); lastProcessTicks.put(pid, info.getUserTime()+ info.getKernelTime());
--- a/agent/src/test/java/com/redhat/thermostat/backend/system/VmCpuStatBuilderTest.java Thu Apr 26 13:29:37 2012 -0400 +++ b/agent/src/test/java/com/redhat/thermostat/backend/system/VmCpuStatBuilderTest.java Thu Apr 26 13:32:33 2012 -0400 @@ -76,6 +76,28 @@ } @Test + public void testBuildNullOnInsufficentInformation() { + int PID = 0; + int cpuCount = 0; + long ticksPerSecond = 0; + final long CLOCK1 = 10000; + final long CLOCK2 = 20000; + final ProcessStatusInfo initialInfo = new ProcessStatusInfo(PID, 1, 2); + final ProcessStatusInfo laterInfo = null; + + Clock clock = mock(Clock.class); + when(clock.getMonotonicTimeNanos()).thenReturn((long) (CLOCK1 * 1E6)).thenReturn((long) (CLOCK2 * 1E6)); + + ProcessStatusInfoBuilder statusBuilder = mock(ProcessStatusInfoBuilder.class); + when(statusBuilder.build(any(Integer.class))).thenReturn(initialInfo).thenReturn(laterInfo).thenReturn(null); + + VmCpuStatBuilder builder = new VmCpuStatBuilder(clock, cpuCount, ticksPerSecond, statusBuilder); + + builder.learnAbout(PID); + assertEquals(null, builder.build(PID)); + } + + @Test public void testSaneBuild() { final int PID = 0;