+
+
+
+
-
+
-
+
diff --git a/javaagent/src/main/java/com/ibm/javametrics/dataproviders/DataProviderManager.java b/javaagent/src/main/java/com/ibm/javametrics/dataproviders/DataProviderManager.java
index 7c0dc95..4cacb03 100644
--- a/javaagent/src/main/java/com/ibm/javametrics/dataproviders/DataProviderManager.java
+++ b/javaagent/src/main/java/com/ibm/javametrics/dataproviders/DataProviderManager.java
@@ -29,7 +29,7 @@ public class DataProviderManager {
private static final String GC_TOPIC = "gc";
private static final String CPU_TOPIC = "cpu";
private static final String MEMORYPOOLS_TOPIC = "memoryPools";
- private static final String ENV_TOPIC = "env";
+ private static final String ENV_TOPIC = "env";
private ScheduledExecutorService exec;
@@ -37,6 +37,16 @@ private static String escapeStringForJSON(String str) {
return str.replace("\\", "\\\\").replace("\"", "\\\"");
}
+ // So long as we get the CPU samples at a constant interval
+ // we can average them out. (Note: the total itself is
+ // not meaningful.)
+ private double totalSystemCPULoad = 0.0;
+ private double totalProcessCPULoad = 0.0;
+ private double cpuLoadSamples = 0.0;
+
+ private long usedHeapAfterGCMax = 0;
+ private long usedNativeMax = 0;
+
/**
* Create a JavametricsMBeanConnector
*/
@@ -75,32 +85,48 @@ private void emitEnvironmentData() {
private void emitGCData() {
long timeStamp = System.currentTimeMillis();
- double gcTime = GCDataProvider.getGCCollectionTime();
- if (gcTime >= 0) { // Don't send -1 'no data' values
+ double gcFraction = GCDataProvider.getLatestGCPercentage();
+ double gcFractionSummary = GCDataProvider.getTotalGCPercentage();
+
+ if (gcFraction >= 0) { // Don't send -1 'no data' values
StringBuilder message = new StringBuilder();
message.append("{\"time\":\"");
message.append(timeStamp);
message.append("\", \"gcTime\": \"");
- message.append(gcTime);
+ message.append(gcFraction);
+ message.append("\", \"gcTimeSummary\": \"");
+ message.append(gcFractionSummary);
message.append("\"}");
Javametrics.getInstance().sendJSON(GC_TOPIC, message.toString());
}
}
private void emitCPUUsage() {
- long timeStamp = System.currentTimeMillis();
- double process = CPUDataProvider.getProcessCpuLoad();
- double system = CPUDataProvider.getSystemCpuLoad();
- if (system >= 0 && process >= 0) {
- StringBuilder message = new StringBuilder();
- message.append("{\"time\":\"");
- message.append(timeStamp);
- message.append("\", \"system\": \"");
- message.append(system);
- message.append("\", \"process\": \"");
- message.append(process);
- message.append("\"}");
- Javametrics.getInstance().sendJSON(CPU_TOPIC, message.toString());
+ try{
+ long timeStamp = System.currentTimeMillis();
+ double process = CPUDataProvider.getProcessCpuLoad();
+ double system = CPUDataProvider.getSystemCpuLoad();
+ cpuLoadSamples++;
+ if (system >= 0 && process >= 0) {
+ totalProcessCPULoad += process;
+ totalSystemCPULoad += system;
+
+ StringBuilder message = new StringBuilder();
+ message.append("{\"time\":\"");
+ message.append(timeStamp);
+ message.append("\", \"system\": \"");
+ message.append(system);
+ message.append("\", \"process\": \"");
+ message.append(process);
+ message.append("\", \"processMean\": \"");
+ message.append(totalProcessCPULoad/cpuLoadSamples);
+ message.append("\", \"systemMean\": \"");
+ message.append(totalSystemCPULoad/cpuLoadSamples);
+ message.append("\"}");
+ Javametrics.getInstance().sendJSON(CPU_TOPIC, message.toString());
+ }
+ } catch (Exception e) {
+ e.printStackTrace();
}
}
@@ -110,17 +136,32 @@ private void emitMemoryPoolUsage() {
long usedNative = MemoryPoolDataProvider.getNativeMemory();
long usedHeap = MemoryPoolDataProvider.getHeapMemory();
if (usedHeapAfterGC >= 0) { // check that some data is available
+ String usedHeapAfterGCStr = Long.toString(usedHeapAfterGC, 10);
+ usedHeapAfterGCMax = Math.max(usedHeapAfterGCMax, usedHeapAfterGC);
+
+ String usedNativeStr = Long.toString(usedNative, 10);
+ usedNativeMax = Math.max(usedNativeMax, usedNative);
+
+ String usedHeapStr = Long.toString(usedHeap, 10);
+
StringBuilder message = new StringBuilder();
message.append("{\"time\":\"");
message.append(timeStamp);
message.append("\", \"usedHeapAfterGC\": \"");
- message.append(usedHeapAfterGC);
+ message.append(usedHeapAfterGCStr);
message.append("\", \"usedHeap\": \"");
- message.append(usedHeap);
+ message.append(usedHeapStr);
message.append("\", \"usedNative\": \"");
- message.append(usedNative);
+ message.append(usedNativeStr);
+
+ // Used heap max is not actually that interesting, it ought to get to 100% just before a GC.
+ message.append("\", \"usedHeapAfterGCMax\": \"");
+ message.append(usedHeapAfterGCMax);
+ message.append("\", \"usedNativeMax\": \"");
+ message.append(usedNativeMax);
message.append("\"}");
Javametrics.getInstance().sendJSON(MEMORYPOOLS_TOPIC, message.toString());
}
}
+
}
diff --git a/javaagent/src/main/java/com/ibm/javametrics/dataproviders/GCDataProvider.java b/javaagent/src/main/java/com/ibm/javametrics/dataproviders/GCDataProvider.java
index 0bcb1a7..5940b52 100644
--- a/javaagent/src/main/java/com/ibm/javametrics/dataproviders/GCDataProvider.java
+++ b/javaagent/src/main/java/com/ibm/javametrics/dataproviders/GCDataProvider.java
@@ -32,20 +32,17 @@ public class GCDataProvider {
/**
* Returns the time spent in GC as a proportion of the time elapsed since
* this method was last called. If no data is available -1 is returned.
- *
+ *
+ * (Will always return -1 on first call.)
+ *
* @return
*/
- public static double getGCCollectionTime() {
+ public static double getLatestGCPercentage() {
long now = System.currentTimeMillis();
- List
sunBeans = ManagementFactory.getGarbageCollectorMXBeans();
- long totalCollectionTime = 0;
- if (sunBeans.size() == 0) {
+ long totalCollectionTime = getTotalCollectionTime();
+ if( totalCollectionTime == -1) {
return -1;
}
- for (Iterator iterator = sunBeans.iterator(); iterator.hasNext();) {
- GarbageCollectorMXBean garbageCollectorMXBean = iterator.next();
- totalCollectionTime += garbageCollectorMXBean.getCollectionTime();
- }
if (previousRequestTimeStamp == 0) {
previousRequestTimeStamp = now;
previousCollectionTime = totalCollectionTime;
@@ -63,4 +60,35 @@ public static double getGCCollectionTime() {
}
}
+ /**
+ * Returns the time spent in GC as a proportion of the time elapsed since
+ * the JVM was started. If no data is available returns -1.
+ *
+ * @return the percentage of uptime spent in gc or -1.0
+ */
+ public static double getTotalGCPercentage() {
+ long totalCollectionTime = getTotalCollectionTime();
+ if(totalCollectionTime == -1) {
+ return -1.0;
+ }
+ long uptime = ManagementFactory.getRuntimeMXBean().getUptime();
+ return ((double) totalCollectionTime / (double) uptime);
+ }
+
+ private static long getTotalCollectionTime() {
+ List sunBeans = ManagementFactory.getGarbageCollectorMXBeans();
+ long totalCollectionTime = 0;
+ if (sunBeans.size() == 0) {
+ return -1;
+ }
+ for (Iterator iterator = sunBeans.iterator(); iterator.hasNext();) {
+ GarbageCollectorMXBean garbageCollectorMXBean = iterator.next();
+ long collectionTime = garbageCollectorMXBean.getCollectionTime();
+ if( collectionTime != -1) {
+ totalCollectionTime += collectionTime;
+ }
+ }
+ return totalCollectionTime;
+ }
+
}
diff --git a/javaagent/src/test/java/com/ibm/javametrics/dataproviders/GCDataProviderTest.java b/javaagent/src/test/java/com/ibm/javametrics/dataproviders/GCDataProviderTest.java
index a4a57d2..711b24e 100644
--- a/javaagent/src/test/java/com/ibm/javametrics/dataproviders/GCDataProviderTest.java
+++ b/javaagent/src/test/java/com/ibm/javametrics/dataproviders/GCDataProviderTest.java
@@ -26,11 +26,11 @@
public class GCDataProviderTest {
/**
- * Test method for {@link com.ibm.javametrics.dataproviders.GCDataProvider#getGCCollectionTime()}.
+ * Test method for {@link com.ibm.javametrics.dataproviders.GCDataProvider#getLatestGCPercentage()}.
*/
@Test
public void testGetGCCollectionTime() {
- double gctime = GCDataProvider.getGCCollectionTime();
+ double gctime = GCDataProvider.getLatestGCPercentage();
int timeout = 3000;
long startTime = System.currentTimeMillis();
// may get -1 returned before MXBeans are initialized, allow time for a
@@ -42,7 +42,7 @@ public void testGetGCCollectionTime() {
// Do nothing
e.printStackTrace();
}
- gctime = GCDataProvider.getGCCollectionTime();
+ gctime = GCDataProvider.getLatestGCPercentage();
}
assertTrue("GC time should be greater than or equal to 0, was " + gctime, gctime >= 0.0d);
assertTrue("GC time should be less than 1 (i.e. less than 100%), was " + gctime, gctime <= 1d);