[김훈민] [PINPOINT-213] garbage collector 통계 개선.

- HotSpot의 Serial, Parallel, CMS, G1 컬렉터 지원.
- 코드 리펙토링. 동적 코드 제거.

git-svn-id: http://svn.bds.nhncorp.com/pe/hippo-tomcat-profiler/trunk@2348 84d0f5b1-2673-498c-a247-62c4ff18d310
This commit is contained in:
Hoonmin Kim
2013-09-25 04:20:39 +00:00
parent 5658e91aad
commit efbd58e7fc
17 changed files with 529 additions and 220 deletions
@@ -4,18 +4,19 @@ import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import com.nhn.pinpoint.common.util.PinpointThreadFactory;
import com.nhn.pinpoint.thrift.dto.AgentInfo;
import com.nhn.pinpoint.thrift.dto.AgentStat;
import com.nhn.pinpoint.thrift.dto.StatWithCmsCollector;
import com.nhn.pinpoint.profiler.monitor.codahale.MetricMonitorMapper;
import com.nhn.pinpoint.profiler.monitor.codahale.MetricMonitorRegistry;
import com.nhn.pinpoint.profiler.config.ProfilerConfig;
import com.nhn.pinpoint.profiler.context.TraceContext;
import com.nhn.pinpoint.profiler.sender.DataSender;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.nhn.pinpoint.common.util.PinpointThreadFactory;
import com.nhn.pinpoint.profiler.config.ProfilerConfig;
import com.nhn.pinpoint.profiler.context.TraceContext;
import com.nhn.pinpoint.profiler.monitor.codahale.MetricMonitorRegistry;
import com.nhn.pinpoint.profiler.monitor.codahale.MetricMonitorValues;
import com.nhn.pinpoint.profiler.monitor.codahale.gc.GarbageCollector;
import com.nhn.pinpoint.profiler.sender.DataSender;
import com.nhn.pinpoint.thrift.dto.AgentInfo;
import com.nhn.pinpoint.thrift.dto.AgentStat;
/**
* AgentStat monitor
*
@@ -72,7 +73,7 @@ public class AgentStatMonitor {
private TraceContext traceContext;
private ProfilerConfig profilerConfig;
private MetricMonitorRegistry monitorRegistry;
private MetricMonitorMapper monitorMapper;
private GarbageCollector garbageCollector;
public CollectJob(DataSender dataSender, TraceContext traceContext, ProfilerConfig profilerConfig) {
this.dataSender = dataSender;
@@ -83,35 +84,26 @@ public class AgentStatMonitor {
this.monitorRegistry = new MetricMonitorRegistry();
// FIXME 설정에 따라 어떤 데이터를 수집할 지 선택할 수 있도록 해야한다. 여기서는 JVM 메모리 정보를 default로 수집.
this.monitorRegistry.registerJvmMemoryMonitor(new MonitorName("jvm", "memory"));
this.monitorRegistry.registerJvmGcMonitor(new MonitorName("jvm", "gc"));
this.monitorRegistry.registerJvmMemoryMonitor(new MonitorName(MetricMonitorValues.JVM_MEMORY));
this.monitorRegistry.registerJvmGcMonitor(new MonitorName(MetricMonitorValues.JVM_GC));
this.monitorMapper = new MetricMonitorMapper();
if (agentInfo != null) {
this.agentStat = new AgentStat();
}
this.garbageCollector = new GarbageCollector();
this.garbageCollector.setType(monitorRegistry);
logger.info("found : {}", this.garbageCollector);
}
public void run() {
// AgentStat 객체를 준비한다.
if (agentInfo != null && this.agentStat == null) {
if (this.monitorRegistry.getRegistry().getNames().contains("jvm.gc.ConcurrentMarkSweep.count")) {
logger.info("found : CMS collector");
StatWithCmsCollector cms = new StatWithCmsCollector();
cms.setAgentId(agentInfo.getAgentId());
this.agentStat = new AgentStat();
this.agentStat.setCms(cms);
}
}
if (this.agentStat == null) {
logger.info("AgentStat is not available");
return;
}
try {
// 통계 Registry에 있는 데이터를 메시지 객체에 매핑한다.
this.monitorMapper.map(this.monitorRegistry, this.agentStat);
garbageCollector.map(monitorRegistry, agentStat, agentInfo.getAgentId());
// send queue에 삽입한다.
dataSender.send(agentStat);
} catch (Exception e) {
logger.warn("AgentStat collect failed : {}", e.getMessage());
e.printStackTrace();
}
}
}
@@ -1,16 +0,0 @@
package com.nhn.pinpoint.profiler.monitor;
import com.nhn.pinpoint.thrift.dto.AgentStat;
import com.nhn.pinpoint.profiler.monitor.MonitorRegistry;
/**
* FIXME common에 동일한 인터페이스가 존재. DTO가 common, profiler 따로따로 있기 때문에
* 일단 복제본을 여기에 둔다.
*/
public interface MonitorMapper {
String convertName(String name);
void map(final MonitorRegistry registry, final AgentStat agentStat);
}
@@ -2,28 +2,10 @@ package com.nhn.pinpoint.profiler.monitor;
public class MonitorName {
public static final String DEFAULT_PREFIX = "common";
private String prefix;
private String subname;
private String name;
public MonitorName(String subname) {
this(DEFAULT_PREFIX, subname);
}
public MonitorName(String prefix, String subname) {
this.prefix = prefix == null ? DEFAULT_PREFIX : prefix;
this.subname = subname == null ? "unknown" : subname;
this.name = this.prefix + "." + this.subname;
}
public String getPrefix() {
return prefix;
}
public String getSubname() {
return subname;
public MonitorName(String name) {
this.name = name;
}
public String getName() {
@@ -8,5 +8,5 @@ public interface MonitorRegistry {
EventRateMonitor newEventRateMonitor(final MonitorName monitorName);
CounterMonitor newCounterMonitor(final MonitorName monitorName);
}
@@ -1,95 +0,0 @@
package com.nhn.pinpoint.profiler.monitor.codahale;
import java.security.InvalidParameterException;
import java.util.Map;
import com.codahale.metrics.Gauge;
import com.codahale.metrics.MetricRegistry;
import com.nhn.pinpoint.thrift.dto.AgentStat;
import com.nhn.pinpoint.thrift.dto.AgentStat._Fields;
import com.nhn.pinpoint.thrift.dto.StatWithCmsCollector;
import com.nhn.pinpoint.thrift.dto.StatWithG1Collector;
import com.nhn.pinpoint.thrift.dto.StatWithParallelCollector;
import com.nhn.pinpoint.profiler.monitor.MonitorMapper;
import com.nhn.pinpoint.profiler.monitor.MonitorRegistry;
/**
* FIXME Thrift DTO가 두 벌(common, profiler)이기 때문에 임시로 복제본을 두었음.
*
* @author harebox
*/
public class MetricMonitorMapper implements MonitorMapper {
/**
* FIXME 성능 개선을 위해 캐싱해 둘 필요 있음.
*/
public String convertName(String name) {
return name.toLowerCase().replace("non_", "non-").replace("_", ".");
}
/**
* @param registry
* @param agentStat
*/
@SuppressWarnings("rawtypes")
public void map(final MonitorRegistry registry, final AgentStat agentStat) {
if (agentStat == null) {
throw new NullPointerException("AgentStat is null");
}
if (agentStat.getSetField() == null) {
throw new NullPointerException("AgentStat has no statistics");
}
if (!(registry instanceof MetricMonitorRegistry)) {
throw new InvalidParameterException("not a MetricMonitorRegistry : " + registry.getClass());
}
MetricRegistry r = ((MetricMonitorRegistry) registry).getRegistry();
Map<String, Gauge> map = r.getGauges();
if (map == null) {
return;
}
// 메시지 타입과 해당 타입에 따른 객체를 얻어온다.
_Fields type = agentStat.getSetField();
Object typeObject = agentStat.getFieldValue(type);
long timestamp = System.currentTimeMillis();
// 타입에 따라 필요한 값을 매핑한다. FIXME 더 좋은 방법 없나?
switch (type) {
case CMS:
StatWithCmsCollector cms = (StatWithCmsCollector) typeObject;
cms.setTimestamp(timestamp);
for (StatWithCmsCollector._Fields each : StatWithCmsCollector.metaDataMap.keySet()) {
Gauge value = map.get(convertName(each.name()));
if (value != null) {
cms.setFieldValue(each, value.getValue());
}
}
break;
case G1:
StatWithG1Collector g1 = (StatWithG1Collector) typeObject;
g1.setTimestamp(timestamp);
for (StatWithG1Collector._Fields each : StatWithG1Collector.metaDataMap.keySet()) {
Gauge value = map.get(convertName(each.name()));
if (value != null) {
g1.setFieldValue(each, value.getValue());
}
}
break;
case PARALLEL:
StatWithParallelCollector parallel = (StatWithParallelCollector) typeObject;
parallel.setTimestamp(timestamp);
for (StatWithParallelCollector._Fields each : StatWithParallelCollector.metaDataMap.keySet()) {
Gauge value = map.get(convertName(each.name()));
if (value != null) {
parallel.setFieldValue(each, value.getValue());
}
}
break;
}
}
}
@@ -1,14 +1,11 @@
package com.nhn.pinpoint.profiler.monitor.codahale;
import java.util.concurrent.TimeUnit;
import com.codahale.metrics.Counter;
import com.codahale.metrics.Histogram;
import com.codahale.metrics.JvmAttributeGaugeSet;
import com.codahale.metrics.Meter;
import com.codahale.metrics.MetricRegistry;
import com.codahale.metrics.SharedMetricRegistries;
import com.codahale.metrics.json.MetricsModule;
import com.codahale.metrics.jvm.GarbageCollectorMetricSet;
import com.codahale.metrics.jvm.MemoryUsageGaugeSet;
import com.codahale.metrics.jvm.ThreadStatesGaugeSet;
@@ -0,0 +1,92 @@
package com.nhn.pinpoint.profiler.monitor.codahale;
import java.util.SortedMap;
import com.codahale.metrics.Gauge;
import com.codahale.metrics.MetricRegistry;
/**
* FIXME 이대로 괜찮은가 -ㅁ-;
*
* @author harebox
*/
public class MetricMonitorValues {
public static final String JVM_GC = "jvm.gc";
// Serial collector
public static final String JVM_GC_SERIAL_COPY_COUNT = JVM_GC + ".Copy.count";
public static final String JVM_GC_SERIAL_COPY_TIME = JVM_GC + ".Copy.time";
public static final String JVM_GC_SERIAL_MSC_COUNT = JVM_GC + ".MarkSweepCompact.count";
public static final String JVM_GC_SERIAL_MSC_TIME = JVM_GC + ".MarkSweepCompact.time";
// Parallel (Old) collector
public static final String JVM_GC_PS_MS_COUNT = JVM_GC + ".PS-MarkSweep.count";
public static final String JVM_GC_PS_MS_TIME = JVM_GC + ".PS-MarkSweep.time";
public static final String JVM_GC_PS_SCAVENGE_COUNT = JVM_GC + ".PS-Scavenge.count";
public static final String JVM_GC_PS_SCAVENGE_TIME = JVM_GC + ".PS-Scavenge.time";
// CMS collector
public static final String JVM_GC_CMS_COUNT = JVM_GC + ".ConcurrentMarkSweep.count";
public static final String JVM_GC_CMS_TIME = JVM_GC + ".ConcurrentMarkSweep.time";
public static final String JVM_GC_PARNEW_COUNT = JVM_GC + ".ParNew.count";
public static final String JVM_GC_PARNEW_TIME = JVM_GC + ".ParNew.time";
// G1 collector
public static final String JVM_GC_G1_OLD_COUNT = JVM_GC + ".G1-Old-Generation.count";
public static final String JVM_GC_G1_OLD_TIME = JVM_GC + ".G1-Old-Generation.time";
public static final String JVM_GC_G1_YOUNG_COUNT = JVM_GC + ".G1-Young-Generation.count";
public static final String JVM_GC_G1_YOUNG_TIME = JVM_GC + ".G1-Young-Generation.time";
public static final String JVM_MEMORY = "jvm.memory";
// commons
public static final String JVM_MEMORY_HEAP_INIT = JVM_MEMORY + ".heap.init";
public static final String JVM_MEMORY_HEAP_USED = JVM_MEMORY + ".heap.used";
public static final String JVM_MEMORY_HEAP_COMMITTED = JVM_MEMORY + ".heap.committed";
public static final String JVM_MEMORY_HEAP_MAX = JVM_MEMORY + ".heap.max";
public static final String JVM_MEMORY_NONHEAP_INIT = JVM_MEMORY + ".non-heap.init";
public static final String JVM_MEMORY_NONHEAP_USED = JVM_MEMORY + ".non-heap.used";
public static final String JVM_MEMORY_NONHEAP_COMMITTED = JVM_MEMORY + ".non-heap.committed";
public static final String JVM_MEMORY_NONHEAP_MAX = JVM_MEMORY + ".non-heap.max";
public static final String JVM_MEMORY_TOTAL_INIT = JVM_MEMORY + ".total.init";
public static final String JVM_MEMORY_TOTAL_USED = JVM_MEMORY + ".total.max";
public static final String JVM_MEMORY_TOTAL_COMMITTED = JVM_MEMORY + ".total.committed";
public static final String JVM_MEMORY_TOTAL_MAX = JVM_MEMORY + ".total.used";
// Serial collector
public static final String JVM_MEMORY_POOLS_EDEN = JVM_MEMORY + ".pools.Eden-Space.usage";
public static final String JVM_MEMORY_POOLS_PERMGEN = JVM_MEMORY + ".pools.Perm-Gen.usage";
public static final String JVM_MEMORY_POOLS_SURVIVOR = JVM_MEMORY + ".pools.Survivor-Space.usage";
public static final String JVM_MEMORY_POOLS_TENURED = JVM_MEMORY + ".pools.Tenured-Gen.usage";
// Parallel (Old) collector
public static final String JVM_MEMORY_POOLS_PS_EDEN = JVM_MEMORY + ".pools.PS-Eden-Space.usage";
public static final String JVM_MEMORY_POOLS_PS_OLDGEN = JVM_MEMORY + ".pools.PS-Old-Gen.usage";
public static final String JVM_MEMORY_POOLS_PS_PERMGEN = JVM_MEMORY + ".pools.PS-Perm-Gen.usage";
public static final String JVM_MEMORY_POOLS_PS_SURVIVOR = JVM_MEMORY + ".pools.PS-Survivor-Space.usage";
// CMS collector
public static final String JVM_MEMORY_POOLS_CMS_OLDGEN = JVM_MEMORY + ".pools.CMS-Old-Gen.usage";
public static final String JVM_MEMORY_POOLS_CMS_PERMGEN = JVM_MEMORY + ".pools.CMS-Perm-Gen.usage";
public static final String JVM_MEMORY_POOLS_CODECACHE = JVM_MEMORY + ".pools.Code-Cache.usage";
public static final String JVM_MEMORY_POOLS_PAREDEN = JVM_MEMORY + ".pools.Par-Eden-Space.usage";
public static final String JVM_MEMORY_POOLS_PARSURVIVOR = JVM_MEMORY + ".pools.Par-Survivor-Space.usage";
// G1 collector
public static final String JVM_MEMORY_POOLS_G1_EDEN = JVM_MEMORY + ".pools.G1-Eden-Space.usage";
public static final String JVM_MEMORY_POOLS_G1_OLDGEN = JVM_MEMORY + ".pools.G1-Old-Gen.usage";
public static final String JVM_MEMORY_POOLS_G1_PERMGEN = JVM_MEMORY + ".pools.G1-Perm-Gen.usage";
public static final String JVM_MEMORY_POOLS_G1_SURVIVOR = JVM_MEMORY + ".pools.G1-Survivor-Space.usage";
@SuppressWarnings("rawtypes")
public static long getLong(MetricRegistry registry, String key) {
SortedMap<String, Gauge> gauges = registry.getGauges();
Gauge gauge = gauges.get(key);
if (gauge == null) {
return 0;
}
Object value = gauge.getValue();
if (value == null) {
return 0;
} else if (value instanceof Long || value instanceof Integer) {
return (Long) value;
} else {
return 0;
}
}
}
@@ -0,0 +1,69 @@
package com.nhn.pinpoint.profiler.monitor.codahale.gc;
import static com.nhn.pinpoint.profiler.monitor.codahale.MetricMonitorValues.JVM_GC_CMS_COUNT;
import static com.nhn.pinpoint.profiler.monitor.codahale.MetricMonitorValues.JVM_GC_CMS_TIME;
import static com.nhn.pinpoint.profiler.monitor.codahale.MetricMonitorValues.JVM_GC_PARNEW_COUNT;
import static com.nhn.pinpoint.profiler.monitor.codahale.MetricMonitorValues.JVM_GC_PARNEW_TIME;
import static com.nhn.pinpoint.profiler.monitor.codahale.MetricMonitorValues.JVM_MEMORY_HEAP_MAX;
import static com.nhn.pinpoint.profiler.monitor.codahale.MetricMonitorValues.JVM_MEMORY_HEAP_USED;
import static com.nhn.pinpoint.profiler.monitor.codahale.MetricMonitorValues.JVM_MEMORY_NONHEAP_MAX;
import static com.nhn.pinpoint.profiler.monitor.codahale.MetricMonitorValues.JVM_MEMORY_NONHEAP_USED;
import static com.nhn.pinpoint.profiler.monitor.codahale.MetricMonitorValues.JVM_MEMORY_POOLS_CMS_OLDGEN;
import static com.nhn.pinpoint.profiler.monitor.codahale.MetricMonitorValues.JVM_MEMORY_POOLS_CMS_PERMGEN;
import static com.nhn.pinpoint.profiler.monitor.codahale.MetricMonitorValues.JVM_MEMORY_POOLS_CODECACHE;
import static com.nhn.pinpoint.profiler.monitor.codahale.MetricMonitorValues.JVM_MEMORY_POOLS_PAREDEN;
import static com.nhn.pinpoint.profiler.monitor.codahale.MetricMonitorValues.JVM_MEMORY_POOLS_PARSURVIVOR;
import static com.nhn.pinpoint.profiler.monitor.codahale.MetricMonitorValues.JVM_MEMORY_TOTAL_MAX;
import static com.nhn.pinpoint.profiler.monitor.codahale.MetricMonitorValues.JVM_MEMORY_TOTAL_USED;
import com.codahale.metrics.MetricRegistry;
import com.nhn.pinpoint.profiler.monitor.codahale.MetricMonitorRegistry;
import com.nhn.pinpoint.profiler.monitor.codahale.MetricMonitorValues;
import com.nhn.pinpoint.thrift.dto.AgentStat;
import com.nhn.pinpoint.thrift.dto.StatWithCmsCollector;
/**
* HotSpot's Concurrent-Mark-Sweep collector
*
* @author harebox
*/
public class CmsCollector extends GarbageCollectorType {
@Override
public int getTypeCode() {
return GarbageCollectorType.CMS_COLLECTOR;
}
@Override
public void map(MetricMonitorRegistry registry, AgentStat agentStat, Object typeObject, String agentId) {
MetricRegistry r = registry.getRegistry();
StatWithCmsCollector stat = (StatWithCmsCollector) typeObject;
if (stat == null) {
stat = new StatWithCmsCollector();
agentStat.setCms(stat);
}
stat.setAgentId(agentId);
stat.setTimestamp(System.currentTimeMillis());
stat.setJvmMemoryTotalMax(MetricMonitorValues.getLong(r, JVM_MEMORY_TOTAL_MAX));
stat.setJvmMemoryTotalUsed(MetricMonitorValues.getLong(r, JVM_MEMORY_TOTAL_USED));
stat.setJvmMemoryHeapMax(MetricMonitorValues.getLong(r, JVM_MEMORY_HEAP_MAX));
stat.setJvmMemoryHeapUsed(MetricMonitorValues.getLong(r, JVM_MEMORY_HEAP_USED));
stat.setJvmMemoryNonHeapMax(MetricMonitorValues.getLong(r, JVM_MEMORY_NONHEAP_MAX));
stat.setJvmMemoryNonHeapUsed(MetricMonitorValues.getLong(r, JVM_MEMORY_NONHEAP_USED));
stat.setJvmMemoryPoolsCodeCacheUsage(MetricMonitorValues.getLong(r, JVM_MEMORY_POOLS_CODECACHE));
stat.setJvmMemoryPoolsParEdenSpaceUsage(MetricMonitorValues.getLong(r, JVM_MEMORY_POOLS_PAREDEN));
stat.setJvmMemoryPoolsParSurvivorSpaceUsage(MetricMonitorValues.getLong(r, JVM_MEMORY_POOLS_PARSURVIVOR));
stat.setJvmMemoryPoolsCMSOldGenUsage(MetricMonitorValues.getLong(r, JVM_MEMORY_POOLS_CMS_OLDGEN));
stat.setJvmMemoryPoolsCMSPermGenUsage(MetricMonitorValues.getLong(r, JVM_MEMORY_POOLS_CMS_PERMGEN));
stat.setJvmGcCmsCount(MetricMonitorValues.getLong(r, JVM_GC_CMS_COUNT));
stat.setJvmGcCmsTime(MetricMonitorValues.getLong(r, JVM_GC_CMS_TIME));
stat.setJvmGcParNewCount(MetricMonitorValues.getLong(r, JVM_GC_PARNEW_COUNT));
stat.setJvmGcParNewTime(MetricMonitorValues.getLong(r, JVM_GC_PARNEW_TIME));
}
@Override
public String toString() {
return "HotSpot's Concurrent-Mark-Sweep collector";
}
}
@@ -0,0 +1,55 @@
package com.nhn.pinpoint.profiler.monitor.codahale.gc;
import com.codahale.metrics.MetricRegistry;
import com.nhn.pinpoint.profiler.monitor.codahale.MetricMonitorRegistry;
import com.nhn.pinpoint.profiler.monitor.codahale.MetricMonitorValues;
import com.nhn.pinpoint.thrift.dto.AgentStat;
import com.nhn.pinpoint.thrift.dto.StatWithG1Collector;
import static com.nhn.pinpoint.profiler.monitor.codahale.MetricMonitorValues.*;
/**
* HotSpot's Garbage-First(G1) collector
*
* @author harebox
*/
public class G1Collector extends GarbageCollectorType {
@Override
public int getTypeCode() {
return GarbageCollectorType.G1_COLLECTOR;
}
@Override
public void map(MetricMonitorRegistry registry, AgentStat agentStat, Object typeObject, String agentId) {
MetricRegistry r = registry.getRegistry();
StatWithG1Collector stat = (StatWithG1Collector) typeObject;
if (stat == null) {
stat = new StatWithG1Collector();
agentStat.setG1(stat);
}
stat.setAgentId(agentId);
stat.setTimestamp(System.currentTimeMillis());
stat.setJvmMemoryTotalMax(MetricMonitorValues.getLong(r, JVM_MEMORY_TOTAL_MAX));
stat.setJvmMemoryTotalUsed(MetricMonitorValues.getLong(r, JVM_MEMORY_TOTAL_USED));
stat.setJvmMemoryHeapMax(MetricMonitorValues.getLong(r, JVM_MEMORY_HEAP_MAX));
stat.setJvmMemoryHeapUsed(MetricMonitorValues.getLong(r, JVM_MEMORY_HEAP_USED));
stat.setJvmMemoryNonHeapMax(MetricMonitorValues.getLong(r, JVM_MEMORY_NONHEAP_MAX));
stat.setJvmMemoryNonHeapUsed(MetricMonitorValues.getLong(r, JVM_MEMORY_NONHEAP_USED));
stat.setJvmMemoryPoolsCodeCacheUsage(MetricMonitorValues.getLong(r, JVM_MEMORY_POOLS_CODECACHE));
stat.setJvmMemoryPoolsG1EdenSpaceUsage(MetricMonitorValues.getLong(r, JVM_MEMORY_POOLS_G1_EDEN));
stat.setJvmMemoryPoolsG1SurvivorSpaceUsage(MetricMonitorValues.getLong(r, JVM_MEMORY_POOLS_G1_SURVIVOR));
stat.setJvmMemoryPoolsG1OldGenUsage(MetricMonitorValues.getLong(r, JVM_MEMORY_POOLS_G1_OLDGEN));
stat.setJvmMemoryPoolsG1PermGenUsage(MetricMonitorValues.getLong(r, JVM_MEMORY_POOLS_G1_PERMGEN));
stat.setJvmGcG1OldGenerationCount(MetricMonitorValues.getLong(r, JVM_GC_G1_OLD_COUNT));
stat.setJvmGcG1OldGenerationTime(MetricMonitorValues.getLong(r, JVM_GC_G1_OLD_TIME));
stat.setJvmGcG1YoungGenerationCount(MetricMonitorValues.getLong(r, JVM_GC_G1_YOUNG_COUNT));
stat.setJvmGcG1YoungGenerationTime(MetricMonitorValues.getLong(r, JVM_GC_G1_YOUNG_TIME));
}
@Override
public String toString() {
return "HotSpot's Garbage-First(G1) collector";
}
}
@@ -0,0 +1,52 @@
package com.nhn.pinpoint.profiler.monitor.codahale.gc;
import com.nhn.pinpoint.profiler.monitor.codahale.MetricMonitorRegistry;
import com.nhn.pinpoint.thrift.dto.AgentStat;
/**
* @author harebox
*/
public class GarbageCollector {
protected GarbageCollectorType type;
public int getType() {
return type.getTypeCode();
}
/**
* 가비지 컬렉터 타입을 지정한다.
*/
public void setType(int type) {
this.type = GarbageCollectorType.newType(type);
}
/**
* Metrics 통계 데이터를 이용하여 가비지 컬렉터 타입을 지정한다.
*/
public void setType(MetricMonitorRegistry registry) {
this.type = GarbageCollectorType.newType(registry);
}
/**
* AgentStat 객체에 통계 데이터를 매핑한다.
*/
public void map(MetricMonitorRegistry registry, AgentStat agentStat, String agentId) {
if (type == null || registry == null || agentStat == null) {
return;
}
Object typeObject = null;
if (agentStat.getSetField() != null) {
typeObject = agentStat.getFieldValue(agentStat.getSetField());
}
type.map(registry, agentStat, typeObject, agentId);
}
public String toString() {
return "GarbageCollector[" + type.toString() + "]";
}
}
@@ -0,0 +1,60 @@
package com.nhn.pinpoint.profiler.monitor.codahale.gc;
import java.util.Collection;
import com.nhn.pinpoint.profiler.monitor.codahale.MetricMonitorRegistry;
import com.nhn.pinpoint.thrift.dto.AgentStat;
import static com.nhn.pinpoint.profiler.monitor.codahale.MetricMonitorValues.*;
/**
* @author harebox
*/
public abstract class GarbageCollectorType {
abstract public int getTypeCode();
abstract public void map(MetricMonitorRegistry registry, AgentStat agentStat, Object typeObject, String agentId);
/**
* 타입 코드로 생성
*/
public static GarbageCollectorType newType(int type) {
if (type == SERIAL_COLLECTOR) {
return new SerialCollector();
} else if (type == PARALLEL_COLLECTOR) {
return new ParallelCollector();
} else if (type == CMS_COLLECTOR) {
return new CmsCollector();
} else if (type == G1_COLLECTOR) {
return new G1Collector();
} else {
throw new IllegalArgumentException("incorrect garbage collector code");
}
}
/**
* 통계 키를 기반으로 생성
*/
public static GarbageCollectorType newType(MetricMonitorRegistry registry) {
Collection<String> keys = registry.getRegistry().getNames();
if (keys.contains(JVM_GC_SERIAL_MSC_COUNT)) {
return new SerialCollector();
} else if (keys.contains(JVM_GC_PS_MS_COUNT)) {
return new ParallelCollector();
} else if (keys.contains(JVM_GC_CMS_COUNT)) {
return new CmsCollector();
} else if (keys.contains(JVM_GC_G1_OLD_COUNT)) {
return new G1Collector();
} else {
throw new RuntimeException("unknown garbage collector");
}
}
// FIXME AgentStat 자체를 타입으로 써도 되지만 일단 이렇게 해둔다.
public static final int SERIAL_COLLECTOR = AgentStat._Fields.SERIAL.ordinal();
public static final int PARALLEL_COLLECTOR = AgentStat._Fields.PARALLEL.ordinal();
public static final int CMS_COLLECTOR = AgentStat._Fields.CMS.ordinal();
public static final int G1_COLLECTOR = AgentStat._Fields.G1.ordinal();
}
@@ -0,0 +1,55 @@
package com.nhn.pinpoint.profiler.monitor.codahale.gc;
import com.codahale.metrics.MetricRegistry;
import com.nhn.pinpoint.profiler.monitor.codahale.MetricMonitorRegistry;
import com.nhn.pinpoint.profiler.monitor.codahale.MetricMonitorValues;
import com.nhn.pinpoint.thrift.dto.AgentStat;
import com.nhn.pinpoint.thrift.dto.StatWithParallelCollector;
import static com.nhn.pinpoint.profiler.monitor.codahale.MetricMonitorValues.*;
/**
* HotSpot's Parallel (Old) collector
*
* @author harebox
*/
public class ParallelCollector extends GarbageCollectorType {
@Override
public int getTypeCode() {
return GarbageCollectorType.PARALLEL_COLLECTOR;
}
@Override
public void map(MetricMonitorRegistry registry, AgentStat agentStat, Object typeObject, String agentId) {
MetricRegistry r = registry.getRegistry();
StatWithParallelCollector stat = (StatWithParallelCollector) typeObject;
if (stat == null) {
stat = new StatWithParallelCollector();
agentStat.setParallel(stat);
}
stat.setAgentId(agentId);
stat.setTimestamp(System.currentTimeMillis());
stat.setJvmMemoryTotalMax(MetricMonitorValues.getLong(r, JVM_MEMORY_TOTAL_MAX));
stat.setJvmMemoryTotalUsed(MetricMonitorValues.getLong(r, JVM_MEMORY_TOTAL_USED));
stat.setJvmMemoryHeapMax(MetricMonitorValues.getLong(r, JVM_MEMORY_HEAP_MAX));
stat.setJvmMemoryHeapUsed(MetricMonitorValues.getLong(r, JVM_MEMORY_HEAP_USED));
stat.setJvmMemoryNonHeapMax(MetricMonitorValues.getLong(r, JVM_MEMORY_NONHEAP_MAX));
stat.setJvmMemoryNonHeapUsed(MetricMonitorValues.getLong(r, JVM_MEMORY_NONHEAP_USED));
stat.setJvmMemoryPoolsCodeCacheUsage(MetricMonitorValues.getLong(r, JVM_MEMORY_POOLS_CODECACHE));
stat.setJvmMemoryPoolsPSEdenSpaceUsage(MetricMonitorValues.getLong(r, JVM_MEMORY_POOLS_PS_EDEN));
stat.setJvmMemoryPoolsPSSurvivorSpaceUsage(MetricMonitorValues.getLong(r, JVM_MEMORY_POOLS_PS_SURVIVOR));
stat.setJvmMemoryPoolsPSOldGenUsage(MetricMonitorValues.getLong(r, JVM_MEMORY_POOLS_PS_OLDGEN));
stat.setJvmMemoryPoolsPSPermGenUsage(MetricMonitorValues.getLong(r, JVM_MEMORY_POOLS_PS_PERMGEN));
stat.setJvmGcPSMarkSweepCount(MetricMonitorValues.getLong(r, JVM_GC_PS_MS_COUNT));
stat.setJvmGcPSMarkSweepTime(MetricMonitorValues.getLong(r, JVM_GC_PS_MS_TIME));
stat.setJvmGcPSScavengeCount(MetricMonitorValues.getLong(r, JVM_GC_PS_SCAVENGE_COUNT));
stat.setJvmGcPSMarkSweepTime(MetricMonitorValues.getLong(r, JVM_GC_PS_SCAVENGE_TIME));
}
@Override
public String toString() {
return "HotSpot's Parallel (Old) collector";
}
}
@@ -0,0 +1,55 @@
package com.nhn.pinpoint.profiler.monitor.codahale.gc;
import com.codahale.metrics.MetricRegistry;
import com.nhn.pinpoint.profiler.monitor.codahale.MetricMonitorRegistry;
import com.nhn.pinpoint.profiler.monitor.codahale.MetricMonitorValues;
import com.nhn.pinpoint.thrift.dto.AgentStat;
import com.nhn.pinpoint.thrift.dto.StatWithSerialCollector;
import static com.nhn.pinpoint.profiler.monitor.codahale.MetricMonitorValues.*;
/**
* HotSpot's Serial collector
*
* @author harebox
*/
public class SerialCollector extends GarbageCollectorType {
@Override
public int getTypeCode() {
return GarbageCollectorType.SERIAL_COLLECTOR;
}
@Override
public void map(MetricMonitorRegistry registry, AgentStat agentStat, Object typeObject, String agentId) {
MetricRegistry r = registry.getRegistry();
StatWithSerialCollector stat = (StatWithSerialCollector) typeObject;
if (stat == null) {
stat = new StatWithSerialCollector();
agentStat.setSerial(stat);
}
stat.setAgentId(agentId);
stat.setTimestamp(System.currentTimeMillis());
stat.setJvmMemoryTotalMax(MetricMonitorValues.getLong(r, JVM_MEMORY_TOTAL_MAX));
stat.setJvmMemoryTotalUsed(MetricMonitorValues.getLong(r, JVM_MEMORY_TOTAL_USED));
stat.setJvmMemoryHeapMax(MetricMonitorValues.getLong(r, JVM_MEMORY_HEAP_MAX));
stat.setJvmMemoryHeapUsed(MetricMonitorValues.getLong(r, JVM_MEMORY_HEAP_USED));
stat.setJvmMemoryNonHeapMax(MetricMonitorValues.getLong(r, JVM_MEMORY_NONHEAP_MAX));
stat.setJvmMemoryNonHeapUsed(MetricMonitorValues.getLong(r, JVM_MEMORY_NONHEAP_USED));
stat.setJvmMemoryPoolsCodeCacheUsage(MetricMonitorValues.getLong(r, JVM_MEMORY_POOLS_CODECACHE));
stat.setJvmMemoryPoolsEdenSpaceUsage(MetricMonitorValues.getLong(r, JVM_MEMORY_POOLS_EDEN));
stat.setJvmMemoryPoolsPermGenUsage(MetricMonitorValues.getLong(r, JVM_MEMORY_POOLS_PERMGEN));
stat.setJvmMemoryPoolsSurvivorSpaceUsage(MetricMonitorValues.getLong(r, JVM_MEMORY_POOLS_SURVIVOR));
stat.setJvmMemoryPoolsTenuredGenUsage(MetricMonitorValues.getLong(r, JVM_MEMORY_POOLS_TENURED));
stat.setJvmGcCopyCount(MetricMonitorValues.getLong(r, JVM_GC_SERIAL_COPY_COUNT));
stat.setJvmGcCopyTime(MetricMonitorValues.getLong(r, JVM_GC_SERIAL_COPY_TIME));
stat.setJvmGcMarkSweepCompactCount(MetricMonitorValues.getLong(r, JVM_GC_SERIAL_MSC_COUNT));
stat.setJvmGcMarkSweepCompactTime(MetricMonitorValues.getLong(r, JVM_GC_SERIAL_MSC_TIME));
}
@Override
public String toString() {
return "HotSpot's Serial collector";
}
}
@@ -0,0 +1,31 @@
package com.nhn.pinpoint.profiler.monitor;
import static org.junit.Assert.*;
import org.junit.Test;
import com.nhn.pinpoint.profiler.context.DefaultTraceContext;
import com.nhn.pinpoint.profiler.context.TraceContext;
import com.nhn.pinpoint.profiler.sender.UdpDataSender;
import com.nhn.pinpoint.thrift.dto.AgentInfo;
public class AgentStatMonitorTest {
@Test
public void test() throws InterruptedException {
System.setProperty("pinpoint.log", ".");
TraceContext context = new DefaultTraceContext();
AgentStatMonitor monitor = new AgentStatMonitor(context, null);
AgentInfo info = new AgentInfo();
info.setAgentId("agentId");
monitor.setAgentInfo(info);
monitor.setDataSender(new UdpDataSender("127.0.0.1", 12345, "udp-sender"));
monitor.start();
while (true) {
Thread.sleep(1000000);
}
}
}
@@ -1,48 +0,0 @@
package com.nhn.pinpoint.profiler.monitor;
import static org.junit.Assert.*;
import org.junit.Test;
import com.nhn.pinpoint.thrift.dto.AgentStat;
import com.nhn.pinpoint.thrift.dto.StatWithCmsCollector;
import com.nhn.pinpoint.profiler.monitor.MonitorName;
import com.nhn.pinpoint.profiler.monitor.codahale.MetricMonitorMapper;
import com.nhn.pinpoint.profiler.monitor.codahale.MetricMonitorRegistry;
/**
* @author harebox
*/
public class MetricMonitorMapperTest {
MetricMonitorMapper mapper = new MetricMonitorMapper();
@Test
public void convertName() {
assertEquals("jvm.memory.total.init", mapper.convertName("JVM_MEMORY_TOTAL_INIT"));
assertEquals("jvm.memory.non-heap.init", mapper.convertName("JVM_MEMORY_NON_HEAP_INIT"));
}
@Test
public void map() {
MetricMonitorRegistry registry = new MetricMonitorRegistry();
registry.registerJvmMemoryMonitor(new MonitorName("jvm", "memory"));
registry.registerJvmGcMonitor(new MonitorName("jvm", "gc"));
// when
AgentStat agentStat = new AgentStat();
assertNull(agentStat.getSetField());
StatWithCmsCollector cms = new StatWithCmsCollector();
agentStat.setCms(cms);
// test
mapper.map(registry, agentStat);
// then
assertTrue(0 < agentStat.getCms().getJvmMemoryTotalMax());
System.out.println(agentStat);
}
}
@@ -24,7 +24,7 @@ public class MetricMonitorRegistryTest {
@Test
public void counter() {
CounterMonitor counter = registry.newCounterMonitor(new MonitorName("test", "counter"));
CounterMonitor counter = registry.newCounterMonitor(new MonitorName("test.counter"));
assertEquals(0, counter.getCount());
counter.incr();
@@ -40,7 +40,7 @@ public class MetricMonitorRegistryTest {
@Test
public void eventRate() {
EventRateMonitor eventRate = registry
.newEventRateMonitor(new MonitorName("test", "eventrate"));
.newEventRateMonitor(new MonitorName("test.eventrate"));
assertEquals(0, eventRate.getCount());
eventRate.event();
@@ -52,7 +52,7 @@ public class MetricMonitorRegistryTest {
@Test
public void histogram() {
HistogramMonitor histogram = registry
.newHistogramMonitor(new MonitorName("test", "histogram"));
.newHistogramMonitor(new MonitorName("test.histogram"));
histogram.update(1);
histogram.update(10);
@@ -68,10 +68,10 @@ public class MetricMonitorRegistryTest {
@Test
public void jvm() {
registry.registerJvmMemoryMonitor(new MonitorName("jvm", "memory"));
registry.registerJvmGcMonitor(new MonitorName("jvm", "gc"));
registry.registerJvmAttributeMonitor(new MonitorName("jvm", "vm"));
registry.registerJvmThreadStatesMonitor(new MonitorName("jvm", "thread"));
registry.registerJvmMemoryMonitor(new MonitorName("jvm.memory"));
registry.registerJvmGcMonitor(new MonitorName("jvm.gc"));
registry.registerJvmAttributeMonitor(new MonitorName("jvm.vm"));
registry.registerJvmThreadStatesMonitor(new MonitorName("jvm.thread"));
boolean hasMemory = false;
boolean hasGc = false;
@@ -0,0 +1,28 @@
package com.nhn.pinpoint.profiler.monitor.codahale.gc;
import static org.junit.Assert.*;
import org.junit.Test;
import com.nhn.pinpoint.profiler.monitor.MonitorName;
import com.nhn.pinpoint.profiler.monitor.codahale.MetricMonitorRegistry;
public class GarbageCollectorTest {
GarbageCollector collector = new GarbageCollector();
MetricMonitorRegistry registry = new MetricMonitorRegistry();
@Test
public void test() {
registry.registerJvmGcMonitor(new MonitorName("jvm.gc"));
registry.registerJvmMemoryMonitor(new MonitorName("jvm.memory"));
try {
collector.setType(registry);
System.out.println(collector.getType());
} catch (Exception e) {
fail("should not be failed");
}
}
}