diff --git a/apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/jvm/JVMService.java b/apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/jvm/JVMService.java index 3fb217ee8..bf413fd22 100644 --- a/apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/jvm/JVMService.java +++ b/apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/jvm/JVMService.java @@ -2,6 +2,7 @@ package org.skywalking.apm.agent.core.jvm; import java.text.SimpleDateFormat; import java.util.Date; +import java.util.List; import java.util.concurrent.Executors; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.ScheduledFuture; @@ -10,14 +11,19 @@ import org.skywalking.apm.agent.core.boot.BootService; import org.skywalking.apm.agent.core.jvm.cpu.CPUProvider; import org.skywalking.apm.agent.core.jvm.memory.MemoryProvider; import org.skywalking.apm.agent.core.jvm.memorypool.MemoryPoolProvider; +import org.skywalking.apm.logging.ILog; +import org.skywalking.apm.logging.LogManager; import org.skywalking.apm.network.proto.JVMMetric; +import org.skywalking.apm.network.proto.MemoryPool; /** * @author wusheng */ public class JVMService implements BootService, Runnable { + private static ILog logger = LogManager.getLogger(JVMService.class); private SimpleDateFormat sdf = new SimpleDateFormat("ss"); private volatile ScheduledFuture scheduledFuture; + private volatile int lastSeconds = -1; @Override public void beforeBoot() throws Throwable { @@ -41,13 +47,21 @@ public class JVMService implements BootService, Runnable { long currentTimeMillis = System.currentTimeMillis(); Date day = new Date(currentTimeMillis); String second = sdf.format(day); - - if (Integer.parseInt(second) % 15 == 0) { - JVMMetric.Builder JVMBuilder = JVMMetric.newBuilder(); - JVMBuilder.setTime(currentTimeMillis); - JVMBuilder.setCpu(CPUProvider.INSTANCE.getCpuMetric()); - JVMBuilder.addAllMemory(MemoryProvider.INSTANCE.getMemoryMetricList()); - JVMBuilder.addAllMemoryPool(MemoryPoolProvider.INSTANCE.getMemoryPoolMetricList()); + int secondInt = Integer.parseInt(second); + if (secondInt % 15 == 0 && secondInt != lastSeconds) { + lastSeconds = secondInt; + try { + JVMMetric.Builder JVMBuilder = JVMMetric.newBuilder(); + JVMBuilder.setTime(currentTimeMillis); + JVMBuilder.setCpu(CPUProvider.INSTANCE.getCpuMetric()); + JVMBuilder.addAllMemory(MemoryProvider.INSTANCE.getMemoryMetricList()); + List memoryPoolMetricList = MemoryPoolProvider.INSTANCE.getMemoryPoolMetricList(); + if (memoryPoolMetricList.size() > 0) { + JVMBuilder.addAllMemoryPool(memoryPoolMetricList); + } + } catch (Exception e) { + logger.error(e, "Collect JVM info fail."); + } } } } diff --git a/apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/jvm/gc/GCMetricAccessor.java b/apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/jvm/gc/GCMetricAccessor.java new file mode 100644 index 000000000..95109ed67 --- /dev/null +++ b/apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/jvm/gc/GCMetricAccessor.java @@ -0,0 +1,11 @@ +package org.skywalking.apm.agent.core.jvm.gc; + +import java.util.List; +import org.skywalking.apm.network.proto.GC; + +/** + * @author wusheng + */ +public interface GCMetricAccessor { + List getGCList(); +} diff --git a/apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/jvm/gc/GCModule.java b/apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/jvm/gc/GCModule.java new file mode 100644 index 000000000..842613453 --- /dev/null +++ b/apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/jvm/gc/GCModule.java @@ -0,0 +1,47 @@ +package org.skywalking.apm.agent.core.jvm.gc; + +import java.lang.management.GarbageCollectorMXBean; +import java.util.LinkedList; +import java.util.List; +import org.skywalking.apm.network.proto.GC; +import org.skywalking.apm.network.proto.GCPhrase; + +/** + * @author wusheng + */ +public abstract class GCModule implements GCMetricAccessor { + private List beans; + + public GCModule(List beans) { + this.beans = beans; + } + + @Override + public List getGCList() { + List gcList = new LinkedList(); + for (GarbageCollectorMXBean bean : beans) { + String name = bean.getName(); + GCPhrase phrase; + if (name.equals(getNewGCName())) { + phrase = GCPhrase.NEW; + } else if (name.equals(getOldGCName())) { + phrase = GCPhrase.OLD; + } else { + continue; + } + + gcList.add( + GC.newBuilder().setPhrase(phrase) + .setCount(bean.getCollectionCount()) + .setTime(bean.getCollectionTime()) + .build() + ); + } + + return gcList; + } + + protected abstract String getOldGCName(); + + protected abstract String getNewGCName(); +} diff --git a/apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/jvm/gc/GCProvider.java b/apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/jvm/gc/GCProvider.java new file mode 100644 index 000000000..1bbf836aa --- /dev/null +++ b/apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/jvm/gc/GCProvider.java @@ -0,0 +1,48 @@ +package org.skywalking.apm.agent.core.jvm.gc; + +import java.lang.management.GarbageCollectorMXBean; +import java.lang.management.ManagementFactory; +import java.util.List; +import org.skywalking.apm.network.proto.GC; + +/** + * @author wusheng + */ +public enum GCProvider { + INSTANCE; + + private GCMetricAccessor metricAccessor; + private List beans; + + GCProvider() { + beans = ManagementFactory.getGarbageCollectorMXBeans(); + for (GarbageCollectorMXBean bean : beans) { + String name = bean.getName(); + GCMetricAccessor accessor = findByBeanName(name); + if (accessor != null) { + metricAccessor = accessor; + break; + } + } + this.metricAccessor = new UnknowGC(); + } + + public List getGCList() { + return metricAccessor.getGCList(); + } + + private GCMetricAccessor findByBeanName(String name) { + if (name.indexOf("PS") > -1) { + //Parallel (Old) collector ( -XX:+UseParallelOldGC ) + } else if (name.indexOf("ConcurrentMarkSweep") > -1) { + // CMS collector ( -XX:+UseConcMarkSweepGC ) + } else if (name.indexOf("G1") > -1) { + // G1 collector ( -XX:+UseG1GC ) + } else if (name.equals("MarkSweepCompact")) { + // Serial collector ( -XX:+UseSerialGC ) + } else { + // Unknown + return null; + } + } +} diff --git a/apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/jvm/gc/ParallelGCModule.java b/apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/jvm/gc/ParallelGCModule.java new file mode 100644 index 000000000..16f1e37c9 --- /dev/null +++ b/apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/jvm/gc/ParallelGCModule.java @@ -0,0 +1,21 @@ +package org.skywalking.apm.agent.core.jvm.gc; + +import java.lang.management.GarbageCollectorMXBean; +import java.util.List; + +/** + * @author wusheng + */ +public class ParallelGCModule extends GCModule { + public ParallelGCModule(List beans) { + super(beans); + } + + @Override protected String getOldGCName() { + return "PS MarkSweep"; + } + + @Override protected String getNewGCName() { + return "PS Scavenge"; + } +} diff --git a/apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/jvm/gc/UnknowGC.java b/apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/jvm/gc/UnknowGC.java new file mode 100644 index 000000000..35b59272a --- /dev/null +++ b/apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/jvm/gc/UnknowGC.java @@ -0,0 +1,19 @@ +package org.skywalking.apm.agent.core.jvm.gc; + +import java.util.LinkedList; +import java.util.List; +import org.skywalking.apm.network.proto.GC; +import org.skywalking.apm.network.proto.GCPhrase; + +/** + * @author wusheng + */ +public class UnknowGC implements GCMetricAccessor { + @Override + public List getGCList() { + List gcList = new LinkedList(); + gcList.add(GC.newBuilder().setPhrase(GCPhrase.NEW).build()); + gcList.add(GC.newBuilder().setPhrase(GCPhrase.OLD).build()); + return gcList; + } +} diff --git a/apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/jvm/memorypool/CMSCollectorModule.java b/apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/jvm/memorypool/CMSCollectorModule.java new file mode 100644 index 000000000..c6a96627f --- /dev/null +++ b/apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/jvm/memorypool/CMSCollectorModule.java @@ -0,0 +1,37 @@ +package org.skywalking.apm.agent.core.jvm.memorypool; + +import java.lang.management.MemoryPoolMXBean; +import java.util.List; + +/** + * @author wusheng + */ +public class CMSCollectorModule extends MemoryPoolModule { + public CMSCollectorModule(List beans) { + super(beans); + } + + @Override protected String getPermName() { + return "CMS Perm Gen"; + } + + @Override protected String getCodeCacheName() { + return "Code Cache"; + } + + @Override protected String getEdenName() { + return "Par Eden Space"; + } + + @Override protected String getOldName() { + return "CMS Old Gen"; + } + + @Override protected String getSurvivorName() { + return "Par Survivor Space"; + } + + @Override protected String getMetaspaceName() { + return "Metaspace"; + } +} diff --git a/apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/jvm/memorypool/G1CollectorModule.java b/apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/jvm/memorypool/G1CollectorModule.java new file mode 100644 index 000000000..cf2d679f5 --- /dev/null +++ b/apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/jvm/memorypool/G1CollectorModule.java @@ -0,0 +1,37 @@ +package org.skywalking.apm.agent.core.jvm.memorypool; + +import java.lang.management.MemoryPoolMXBean; +import java.util.List; + +/** + * @author wusheng + */ +public class G1CollectorModule extends MemoryPoolModule { + public G1CollectorModule(List beans) { + super(beans); + } + + @Override protected String getPermName() { + return "G1 Perm Gen"; + } + + @Override protected String getCodeCacheName() { + return "Code Cache"; + } + + @Override protected String getEdenName() { + return "G1 Eden Space"; + } + + @Override protected String getOldName() { + return "G1 Old Gen"; + } + + @Override protected String getSurvivorName() { + return "G1 Survivor Space"; + } + + @Override protected String getMetaspaceName() { + return "Metaspace"; + } +} diff --git a/apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/jvm/memorypool/MemoryPoolModule.java b/apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/jvm/memorypool/MemoryPoolModule.java index 5e1ccf258..cf0744ca5 100644 --- a/apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/jvm/memorypool/MemoryPoolModule.java +++ b/apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/jvm/memorypool/MemoryPoolModule.java @@ -35,17 +35,17 @@ public abstract class MemoryPoolModule implements MemoryPoolMetricAccessor { type = PoolType.METASPACE_USAGE; } else if (name.equals(getPermName())) { type = PoolType.PERMGEN_USAGE; + } else { + continue; } - if (type != null) { - MemoryUsage usage = bean.getUsage(); - poolList.add(MemoryPool.newBuilder().setType(type) - .setInit(usage.getInit()) - .setMax(usage.getMax()) - .setCommited(usage.getCommitted()) - .setUsed(usage.getUsed()) - .build()); - } + MemoryUsage usage = bean.getUsage(); + poolList.add(MemoryPool.newBuilder().setType(type) + .setInit(usage.getInit()) + .setMax(usage.getMax()) + .setCommited(usage.getCommitted()) + .setUsed(usage.getUsed()) + .build()); } return poolList; } diff --git a/apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/jvm/memorypool/MemoryPoolProvider.java b/apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/jvm/memorypool/MemoryPoolProvider.java index 31399872f..28f1e4caa 100644 --- a/apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/jvm/memorypool/MemoryPoolProvider.java +++ b/apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/jvm/memorypool/MemoryPoolProvider.java @@ -39,10 +39,10 @@ public enum MemoryPoolProvider { return new ParallelCollectorModule(beans); } else if (name.indexOf("CMS") > -1) { // CMS collector ( -XX:+UseConcMarkSweepGC ) - return null; + return new CMSCollectorModule(beans); } else if (name.indexOf("G1") > -1) { // G1 collector ( -XX:+UseG1GC ) - return null; + return new G1CollectorModule(beans); } else if (name.equals("Survivor Space")) { // Serial collector ( -XX:+UseSerialGC ) return new SerialCollectorModule(beans); diff --git a/apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/jvm/memorypool/ParallelCollectorModule.java b/apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/jvm/memorypool/ParallelCollectorModule.java index d2c6fda63..6b108943b 100644 --- a/apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/jvm/memorypool/ParallelCollectorModule.java +++ b/apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/jvm/memorypool/ParallelCollectorModule.java @@ -6,7 +6,7 @@ import java.util.List; /** * @author wusheng */ -public class ParallelCollectorModule extends MemoryPoolModule{ +public class ParallelCollectorModule extends MemoryPoolModule { public ParallelCollectorModule(List beans) { super(beans); diff --git a/apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/jvm/memorypool/UnknownMemoryPool.java b/apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/jvm/memorypool/UnknownMemoryPool.java index 91755cafa..2adb2f95a 100644 --- a/apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/jvm/memorypool/UnknownMemoryPool.java +++ b/apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/jvm/memorypool/UnknownMemoryPool.java @@ -18,6 +18,6 @@ public class UnknownMemoryPool implements MemoryPoolMetricAccessor { poolList.add(MemoryPool.newBuilder().setType(PoolType.SURVIVOR_USAGE).build()); poolList.add(MemoryPool.newBuilder().setType(PoolType.PERMGEN_USAGE).build()); poolList.add(MemoryPool.newBuilder().setType(PoolType.METASPACE_USAGE).build()); - return poolList; + return new LinkedList(); } }