mirror of
https://github.com/wahyd4/pinpoint.git
synced 2026-08-09 12:56:12 +10:00
[#49] Created pinpoint-test project.
Tested pinoint-arcus project and fixed bugs
This commit is contained in:
@@ -4,3 +4,4 @@
|
||||
/*.iml
|
||||
/deploy
|
||||
/target
|
||||
/build/
|
||||
|
||||
+4
-3
@@ -3,11 +3,11 @@
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<parent>
|
||||
<groupId>com.nhn.pinpoint</groupId>
|
||||
<artifactId>pinpoint-plugins</artifactId>
|
||||
<artifactId>pom</artifactId>
|
||||
<version>1.0.4-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>pinpoint-arcus-plugin</artifactId>
|
||||
<artifactId>pinpoint-arcus</artifactId>
|
||||
<name>pinpoint arcus plugin</name>
|
||||
<packaging>jar</packaging>
|
||||
|
||||
@@ -92,8 +92,9 @@
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-jar-plugin</artifactId>
|
||||
|
||||
<configuration>
|
||||
<outputDirectory>${pinpiont-plugin-dir}</outputDirectory>
|
||||
<outputDirectory>../${pinpoint.agent.plugin.directory}</outputDirectory>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
|
||||
@@ -4,43 +4,199 @@ import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import com.nhn.pinpoint.bootstrap.instrument.InstrumentClass;
|
||||
import com.nhn.pinpoint.bootstrap.instrument.MethodInfo;
|
||||
import com.nhn.pinpoint.bootstrap.interceptor.ParameterExtractor;
|
||||
import com.nhn.pinpoint.bootstrap.plugin.ClassEditor;
|
||||
import com.nhn.pinpoint.bootstrap.plugin.ClassEditorBuilder;
|
||||
import com.nhn.pinpoint.bootstrap.plugin.ClassEditorFactoryMapping;
|
||||
import com.nhn.pinpoint.bootstrap.plugin.Condition;
|
||||
import com.nhn.pinpoint.bootstrap.plugin.ParameterExtractorFactory;
|
||||
import com.nhn.pinpoint.bootstrap.plugin.ProfilerPlugin;
|
||||
import com.nhn.pinpoint.bootstrap.plugin.ProfilerPluginContext;
|
||||
import com.nhn.pinpoint.plugin.arcus.filter.ArcusMethodFilter;
|
||||
import com.nhn.pinpoint.plugin.arcus.filter.FrontCacheMemcachedMethodFilter;
|
||||
import com.nhn.pinpoint.plugin.arcus.filter.MemcachedMethodFilter;
|
||||
|
||||
// TODO split arcus plugin and memcached plugin
|
||||
public class ArcusPlugin implements ProfilerPlugin {
|
||||
@Override
|
||||
public List<ClassEditorFactoryMapping> getClassEditorMappings(ProfilerPluginContext context) {
|
||||
public List<ClassEditor> getClassEditors(ProfilerPluginContext context) {
|
||||
boolean arcus = context.getConfig().isArucs();
|
||||
boolean memcached = context.getConfig().isMemcached();
|
||||
|
||||
List<ClassEditorFactoryMapping> editors = new ArrayList<ClassEditorFactoryMapping>();
|
||||
List<ClassEditor> editors = new ArrayList<ClassEditor>();
|
||||
|
||||
if (arcus) {
|
||||
editors.add(new ClassEditorFactoryMapping("net.spy.memcached.ArcusClient", "com.nhn.pinpoint.plugin.arcus.ArcusClientEditorFactory"));
|
||||
editors.add(new ClassEditorFactoryMapping("net.spy.memcached.internal.CollectionFuture", "com.nhn.pinpoint.plugin.arcus.FutureEditorFactory"));
|
||||
if (arcus) {
|
||||
editors.add(getArcusClientEditor(context));
|
||||
editors.add(getCollectionFutureEditor(context));
|
||||
}
|
||||
|
||||
if (arcus || memcached) {
|
||||
editors.add(new ClassEditorFactoryMapping("net.spy.memcached.protocol.BaseOperationImpl", "com.nhn.pinpoint.plugin.arcus.BaseOperationImplEditorFactory"));
|
||||
editors.add(new ClassEditorFactoryMapping("net.spy.memcached.CacheManager", "com.nhn.pinpoint.plugin.arcus.BaseCacheManagerEditorFactory"));
|
||||
editors.add(getBaseOperationImplEditor(context));
|
||||
editors.add(getCacheManagerEditor(context));
|
||||
|
||||
editors.add(new ClassEditorFactoryMapping("net.spy.memcached.internal.GetFuture", "com.nhn.pinpoint.plugin.arcus.FutureEditorFactory"));
|
||||
editors.add(new ClassEditorFactoryMapping("net.spy.memcached.internal.ImmediateFuture", "com.nhn.pinpoint.plugin.arcus.FutureEditorFactory"));
|
||||
editors.add(new ClassEditorFactoryMapping("net.spy.memcached.internal.OperationFuture", "com.nhn.pinpoint.plugin.arcus.FutureEditorFactory"));
|
||||
editors.add(getGetFutureEditor(context));
|
||||
// TODO ImmedateFuture doesn't have setOperation(Operation) method.
|
||||
// editors.add(getImmediateFutureEditor(context));
|
||||
editors.add(getOperationFutureEditor(context));
|
||||
|
||||
editors.add(new ClassEditorFactoryMapping("net.spy.memcached.plugin.FrontCacheGetFuture", "com.nhn.pinpoint.plugin.arcus.FrontCacheGetFutureEditorFactory"));
|
||||
editors.add(new ClassEditorFactoryMapping("net.spy.memcached.plugin.FrontCacheMemcachedClient", "com.nhn.pinpoint.plugin.arcus.FrontCacheMemcachedClientEditorFactory"));
|
||||
editors.add(new ClassEditorFactoryMapping("net.spy.memcached.MemcachedClient", "com.nhn.pinpoint.plugin.arcus.MemcachedClientEditorFactory"));
|
||||
editors.add(getFrontCacheGetFutureEditor(context));
|
||||
editors.add(getFrontCacheMemcachedClientEditor(context));
|
||||
editors.add(getMemcachedClientEditor(context));
|
||||
}
|
||||
|
||||
return editors;
|
||||
}
|
||||
}
|
||||
|
||||
private ClassEditor getArcusClientEditor(ProfilerPluginContext context) {
|
||||
boolean traceArcusKey = context.getConfig().isArucsKeyTrace();
|
||||
ClassEditorBuilder builder = context.newClassEditorBuilder();
|
||||
|
||||
builder.edit("net.spy.memcached.ArcusClient");
|
||||
builder.when(new Condition() {
|
||||
@Override
|
||||
public boolean check(InstrumentClass target) {
|
||||
return target.hasMethod("addOp", new String[] {"java.lang.String", "net.spy.memcached.ops.Operation"}, "net.spy.memcached.ops.Operation");
|
||||
}
|
||||
});
|
||||
|
||||
builder.intercept("setCacheManager", "net.spy.memcached.CacheManager")
|
||||
.with("com.nhn.pinpoint.plugin.arcus.interceptor.SetCacheManagerInterceptor");
|
||||
|
||||
builder.interceptMethodsFilteredBy(new ArcusMethodFilter())
|
||||
.with("com.nhn.pinpoint.plugin.arcus.interceptor.ApiInterceptor")
|
||||
.in(Commons.ARCUS_SCOPE)
|
||||
.using(traceArcusKey ? Commons.ARCUS_KEY_EXTRACTOR_FACTORY : null);
|
||||
|
||||
return builder.build();
|
||||
}
|
||||
|
||||
private ClassEditor getCacheManagerEditor(ProfilerPluginContext context) {
|
||||
ClassEditorBuilder builder = context.newClassEditorBuilder();
|
||||
|
||||
builder.edit("net.spy.memcached.CacheManager");
|
||||
|
||||
builder.inject("com.nhn.pinpoint.plugin.arcus.accessor.ServiceCodeAccessor");
|
||||
|
||||
builder.interceptConstructor("java.lang.String", "java.lang.String", "net.spy.memcached.ConnectionFactoryBuilder", "java.util.concurrent.CountDownLatch", "int", "int")
|
||||
.with("com.nhn.pinpoint.plugin.arcus.interceptor.CacheManagerConstructInterceptor");
|
||||
|
||||
return builder.build();
|
||||
}
|
||||
|
||||
|
||||
private ClassEditor getBaseOperationImplEditor(ProfilerPluginContext context) {
|
||||
ClassEditorBuilder builder = context.newClassEditorBuilder();
|
||||
|
||||
builder.edit("net.spy.memcached.protocol.BaseOperationImpl");
|
||||
|
||||
builder.inject("com.nhn.pinpoint.plugin.arcus.accessor.ServiceCodeAccessor");
|
||||
|
||||
return builder.build();
|
||||
}
|
||||
|
||||
private ClassEditor getFrontCacheGetFutureEditor(ProfilerPluginContext context) {
|
||||
ClassEditorBuilder builder = context.newClassEditorBuilder();
|
||||
|
||||
builder.edit("net.spy.memcached.plugin.FrontCacheGetFuture");
|
||||
|
||||
builder.inject("com.nhn.pinpoint.plugin.arcus.accessor.CacheNameAccessor");
|
||||
builder.inject("com.nhn.pinpoint.plugin.arcus.accessor.CacheKeyAccessor");
|
||||
|
||||
builder.interceptConstructor("net.sf.ehcache.Element")
|
||||
.with("com.nhn.pinpoint.plugin.arcus.interceptor.FrontCacheGetFutureConstructInterceptor");
|
||||
builder.intercept("get", "long", "java.util.concurrent.TimeUnit")
|
||||
.with("com.nhn.pinpoint.plugin.arcus.interceptor.FrontCacheGetFutureGetInterceptor")
|
||||
.in(Commons.ARCUS_SCOPE);
|
||||
builder.intercept("get")
|
||||
.with("com.nhn.pinpoint.plugin.arcus.interceptor.FrontCacheGetFutureGetInterceptor")
|
||||
.in(Commons.ARCUS_SCOPE);
|
||||
|
||||
return builder.build();
|
||||
}
|
||||
|
||||
private ClassEditor getFrontCacheMemcachedClientEditor(ProfilerPluginContext context) {
|
||||
boolean traceArcusKey = context.getConfig().isArucsKeyTrace();
|
||||
ClassEditorBuilder builder = context.newClassEditorBuilder();
|
||||
|
||||
builder.edit("net.spy.memcached.plugin.FrontCacheMemcachedClient");
|
||||
builder.when(new Condition() {
|
||||
|
||||
@Override
|
||||
public boolean check(InstrumentClass target) {
|
||||
return target.hasDeclaredMethod("putFrontCache", new String[] { "java.lang.String", "java.util.concurrent.Future", "long" });
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
builder.interceptMethodsFilteredBy(new FrontCacheMemcachedMethodFilter())
|
||||
.with("com.nhn.pinpoint.plugin.arcus.interceptor.ApiInterceptor")
|
||||
.in(Commons.ARCUS_SCOPE)
|
||||
.using(traceArcusKey ? Commons.ARCUS_KEY_EXTRACTOR_FACTORY : null);
|
||||
|
||||
return builder.build();
|
||||
}
|
||||
|
||||
|
||||
private ClassEditor getMemcachedClientEditor(ProfilerPluginContext context) {
|
||||
boolean traceArcusKey = context.getConfig().isArucsKeyTrace();
|
||||
ClassEditorBuilder builder = context.newClassEditorBuilder();
|
||||
|
||||
builder.edit("net.spy.memcached.MemcachedClient");
|
||||
builder.when(new Condition() {
|
||||
|
||||
@Override
|
||||
public boolean check(InstrumentClass target) {
|
||||
return target.hasDeclaredMethod("addOp", new String[] { "java.lang.String", "net.spy.memcached.ops.Operation" });
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
|
||||
builder.inject("com.nhn.pinpoint.plugin.arcus.accessor.ServiceCodeAccessor");
|
||||
|
||||
builder.intercept("addOp", "java.lang.String", "net.spy.memcached.ops.Operation")
|
||||
.with("com.nhn.pinpoint.plugin.arcus.interceptor.AddOpInterceptor");
|
||||
|
||||
builder.interceptMethodsFilteredBy(new MemcachedMethodFilter())
|
||||
.with("com.nhn.pinpoint.plugin.arcus.interceptor.ApiInterceptor")
|
||||
.in(Commons.ARCUS_SCOPE)
|
||||
.using(traceArcusKey ? Commons.ARCUS_KEY_EXTRACTOR_FACTORY : null);
|
||||
|
||||
return builder.build();
|
||||
}
|
||||
|
||||
private ClassEditor getFutureEditor(ClassEditorBuilder builder) {
|
||||
builder.inject("com.nhn.pinpoint.plugin.arcus.accessor.OperationAccessor");
|
||||
|
||||
builder.intercept("setOperation", "net.spy.memcached.ops.Operation")
|
||||
.with("com.nhn.pinpoint.plugin.arcus.interceptor.FutureSetOperationInterceptor");
|
||||
|
||||
builder.intercept("get", "long", "java.util.concurrent.TimeUnit")
|
||||
.with("com.nhn.pinpoint.plugin.arcus.interceptor.FutureGetInterceptor")
|
||||
.in(Commons.ARCUS_SCOPE);
|
||||
|
||||
return builder.build();
|
||||
}
|
||||
|
||||
private ClassEditor getCollectionFutureEditor(ProfilerPluginContext context) {
|
||||
ClassEditorBuilder builder = context.newClassEditorBuilder();
|
||||
builder.edit("net.spy.memcached.internal.CollectionFuture");
|
||||
return getFutureEditor(builder);
|
||||
}
|
||||
|
||||
private ClassEditor getGetFutureEditor(ProfilerPluginContext context) {
|
||||
ClassEditorBuilder builder = context.newClassEditorBuilder();
|
||||
builder.edit("net.spy.memcached.internal.GetFuture");
|
||||
return getFutureEditor(builder);
|
||||
}
|
||||
|
||||
private ClassEditor getOperationFutureEditor(ProfilerPluginContext context) {
|
||||
ClassEditorBuilder builder = context.newClassEditorBuilder();
|
||||
builder.edit("net.spy.memcached.internal.OperationFuture");
|
||||
return getFutureEditor(builder);
|
||||
}
|
||||
|
||||
private ClassEditor getImmediateFutureEditor(ProfilerPluginContext context) {
|
||||
ClassEditorBuilder builder = context.newClassEditorBuilder();
|
||||
builder.edit("net.spy.memcached.internal.ImmediateFuture");
|
||||
return getFutureEditor(builder);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -19,7 +19,11 @@ import com.nhn.pinpoint.plugin.arcus.accessor.ServiceCodeAccessor;
|
||||
*/
|
||||
public class ApiInterceptor extends SpanEventSimpleAroundInterceptor {
|
||||
private final ParameterExtractor parameterExtractor;
|
||||
|
||||
|
||||
public ApiInterceptor() {
|
||||
this(null);
|
||||
}
|
||||
|
||||
public ApiInterceptor(ParameterExtractor parameterExtractor) {
|
||||
super(ApiInterceptor.class);
|
||||
this.parameterExtractor = parameterExtractor;
|
||||
|
||||
-4
@@ -8,14 +8,10 @@ import net.spy.memcached.ops.Operation;
|
||||
|
||||
import com.nhn.pinpoint.bootstrap.context.Trace;
|
||||
import com.nhn.pinpoint.bootstrap.context.TraceContext;
|
||||
import com.nhn.pinpoint.bootstrap.interceptor.ByteCodeMethodDescriptorSupport;
|
||||
import com.nhn.pinpoint.bootstrap.interceptor.MethodDescriptor;
|
||||
import com.nhn.pinpoint.bootstrap.interceptor.SimpleAroundInterceptor;
|
||||
import com.nhn.pinpoint.bootstrap.interceptor.TargetClassLoader;
|
||||
import com.nhn.pinpoint.bootstrap.interceptor.TraceContextSupport;
|
||||
import com.nhn.pinpoint.bootstrap.logging.PLogger;
|
||||
import com.nhn.pinpoint.bootstrap.logging.PLoggerFactory;
|
||||
import com.nhn.pinpoint.bootstrap.util.MetaObject;
|
||||
import com.nhn.pinpoint.common.ServiceType;
|
||||
import com.nhn.pinpoint.plugin.arcus.accessor.OperationAccessor;
|
||||
import com.nhn.pinpoint.plugin.arcus.accessor.ServiceCodeAccessor;
|
||||
|
||||
+1
@@ -0,0 +1 @@
|
||||
com.nhn.pinpoint.plugin.arcus.ArcusPlugin
|
||||
@@ -0,0 +1,58 @@
|
||||
package com.nhn.pinpoint.plugin.arcus;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
|
||||
import com.nhn.pinpoint.plugin.arcus.accessor.CacheKeyAccessor;
|
||||
import com.nhn.pinpoint.plugin.arcus.accessor.CacheNameAccessor;
|
||||
import com.nhn.pinpoint.plugin.arcus.accessor.OperationAccessor;
|
||||
import com.nhn.pinpoint.plugin.arcus.accessor.ServiceCodeAccessor;
|
||||
import com.nhn.pinpoint.test.fork.ForkRunner;
|
||||
import com.nhn.pinpoint.test.fork.OnChildClassLoader;
|
||||
import com.nhn.pinpoint.test.fork.PinpointAgentPath;
|
||||
import com.nhn.pinpoint.test.fork.PinpointConfig;
|
||||
|
||||
@RunWith(ForkRunner.class)
|
||||
@PinpointConfig("target/test-classes/pinpoint-test.config")
|
||||
@PinpointAgentPath("../build/pinpoint-agent")
|
||||
@OnChildClassLoader
|
||||
public class ArcusPluginIT {
|
||||
|
||||
// TODO how to test intercpetor?
|
||||
|
||||
@Test
|
||||
public void test() throws Exception {
|
||||
|
||||
Class<?> arcusClient = Class.forName("net.spy.memcached.ArcusClient");
|
||||
|
||||
Class<?> cacheManager = Class.forName("net.spy.memcached.CacheManager");
|
||||
assertTrue(ServiceCodeAccessor.class.isAssignableFrom(cacheManager));
|
||||
|
||||
Class<?> collectionFuture = Class.forName("net.spy.memcached.internal.CollectionFuture");
|
||||
assertTrue(OperationAccessor.class.isAssignableFrom(collectionFuture));
|
||||
|
||||
Class<?> baseOperationImpl = Class.forName("net.spy.memcached.protocol.BaseOperationImpl");
|
||||
assertTrue(ServiceCodeAccessor.class.isAssignableFrom(baseOperationImpl));
|
||||
|
||||
|
||||
Class<?> getFuture = Class.forName("net.spy.memcached.internal.GetFuture");
|
||||
assertTrue(OperationAccessor.class.isAssignableFrom(getFuture));
|
||||
|
||||
Class<?> immediateFuture = Class.forName("net.spy.memcached.internal.ImmediateFuture");
|
||||
// assertTrue(OperationAccessor.class.isAssignableFrom(immediateFuture));
|
||||
|
||||
Class<?> operationFuture = Class.forName("net.spy.memcached.internal.OperationFuture");
|
||||
assertTrue(OperationAccessor.class.isAssignableFrom(operationFuture));
|
||||
|
||||
Class<?> frontCacheGetFuture = Class.forName("net.spy.memcached.plugin.FrontCacheGetFuture");
|
||||
assertTrue(CacheNameAccessor.class.isAssignableFrom(frontCacheGetFuture));
|
||||
assertTrue(CacheKeyAccessor.class.isAssignableFrom(frontCacheGetFuture));
|
||||
|
||||
Class<?> frontCacheMemcachedClient = Class.forName("net.spy.memcached.plugin.FrontCacheMemcachedClient");
|
||||
|
||||
Class<?> memcachedClient = Class.forName("net.spy.memcached.MemcachedClient");
|
||||
assertTrue(ServiceCodeAccessor.class.isAssignableFrom(memcachedClient));
|
||||
}
|
||||
}
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
package com.nhn.pinpoint.profiler.modifier.arcus;
|
||||
package com.nhn.pinpoint.plugin.arcus;
|
||||
|
||||
import com.nhn.pinpoint.common.bo.SpanEventBo;
|
||||
import com.nhn.pinpoint.profiler.junit4.BasePinpointTest;
|
||||
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
package com.nhn.pinpoint.profiler.modifier.arcus.interceptor;
|
||||
package com.nhn.pinpoint.plugin.arcus.interceptor;
|
||||
|
||||
import static org.mockito.Mockito.*;
|
||||
|
||||
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
package com.nhn.pinpoint.profiler.modifier.arcus.interceptor;
|
||||
package com.nhn.pinpoint.plugin.arcus.interceptor;
|
||||
|
||||
import junit.framework.Assert;
|
||||
import net.spy.memcached.ops.OperationState;
|
||||
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
package com.nhn.pinpoint.profiler.modifier.arcus.interceptor;
|
||||
package com.nhn.pinpoint.plugin.arcus.interceptor;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
import static org.mockito.Mockito.*;
|
||||
|
||||
@@ -0,0 +1,186 @@
|
||||
#
|
||||
# Pinpoint agent configuration
|
||||
# (Phase : local)
|
||||
#
|
||||
|
||||
###########################################################
|
||||
# Collector server #
|
||||
###########################################################
|
||||
# 로컬
|
||||
profiler.collector.ip=127.0.0.1
|
||||
# 개발
|
||||
#profiler.collector.ip=10.64.84.188
|
||||
# 운영
|
||||
#profiler.collector.ip=10.25.149.249
|
||||
|
||||
profiler.collector.udpspan.port=9996
|
||||
profiler.collector.udp.port=9995
|
||||
profiler.collector.tcp.port=9994
|
||||
|
||||
|
||||
###########################################################
|
||||
# Profiler Global Configuration #
|
||||
###########################################################
|
||||
profiler.enable=true
|
||||
|
||||
profiler.jvm.collect.interval=1000
|
||||
|
||||
profiler.sampling.enable=true
|
||||
|
||||
# 아래 지정한 값중 한 개의 트랜잭션을 수집합니다. (예를들어 1로 지정하면 100%수집, 2로 지정하면 50%수집 셈)
|
||||
profiler.sampling.rate=1
|
||||
|
||||
# span을 Io에 flush할 경우 buffering 여부
|
||||
profiler.io.buffering.enable=true
|
||||
|
||||
# buffering 시 몇개 까지 저장할지 여부
|
||||
profiler.io.buffering.buffersize=20
|
||||
|
||||
|
||||
|
||||
profiler.spandatasender.write.queue.size=5120
|
||||
#profiler.spandatasender.socket.sendbuffersize=1048576
|
||||
#profiler.spandatasender.socket.timeout=3000
|
||||
|
||||
profiler.statdatasender.write.queue.size=5120
|
||||
#profiler.statdatasender.socket.sendbuffersize=1048576
|
||||
#profiler.statdatasender.socket.timeout=3000
|
||||
|
||||
profiler.heartbeat.interval=300000
|
||||
|
||||
# Tcp Data Command 허용 여부
|
||||
profiler.tcpdatasender.command.accept.enable=true
|
||||
|
||||
###########################################################
|
||||
# application type #
|
||||
###########################################################
|
||||
#profiler.applicationservertype=TOMCAT
|
||||
#profiler.applicationservertype=BLOC
|
||||
|
||||
|
||||
###########################################################
|
||||
# user defined classes #
|
||||
###########################################################
|
||||
profiler.include=com.nhn.pinpoint.testweb.controller.*,com.nhn.pinpoint.testweb.MyClass
|
||||
|
||||
|
||||
###########################################################
|
||||
# JDBC #
|
||||
###########################################################
|
||||
profiler.jdbc=true
|
||||
profiler.jdbc.sqlcachesize=1024
|
||||
profiler.jdbc.maxsqlbindvaluesize=1024
|
||||
|
||||
#
|
||||
# MYSQL
|
||||
#
|
||||
profiler.jdbc.mysql=true
|
||||
profiler.jdbc.mysql.setautocommit=true
|
||||
profiler.jdbc.mysql.commit=true
|
||||
profiler.jdbc.mysql.rollback=true
|
||||
|
||||
#
|
||||
# MSSQL
|
||||
#
|
||||
profiler.jdbc.mssql=false
|
||||
|
||||
#
|
||||
# Oracle
|
||||
#
|
||||
profiler.jdbc.oracle=true
|
||||
profiler.jdbc.oracle.setautocommit=true
|
||||
profiler.jdbc.oracle.commit=true
|
||||
profiler.jdbc.oracle.rollback=true
|
||||
|
||||
#
|
||||
# CUBRID
|
||||
#
|
||||
profiler.jdbc.cubrid=true
|
||||
profiler.jdbc.cubrid.setautocommit=true
|
||||
profiler.jdbc.cubrid.commit=true
|
||||
profiler.jdbc.cubrid.rollback=true
|
||||
|
||||
#
|
||||
# DBCP
|
||||
#
|
||||
profiler.jdbc.dbcp=true
|
||||
profiler.jdbc.dbcp.connectionclose=true
|
||||
|
||||
|
||||
###########################################################
|
||||
# Apache HTTP Client 4.x #
|
||||
###########################################################
|
||||
profiler.apache.httpclient4=true
|
||||
profiler.apache.httpclient4.cookie=true
|
||||
|
||||
# cookie를 언제 덤프할지 결정. ALWAYS or EXCEPTION 2가지
|
||||
profiler.apache.httpclient4.cookie.dumptype=ALWAYS
|
||||
profiler.apache.httpclient4.cookie.sampling.rate=1
|
||||
|
||||
# post, put의 entity를 덤프한다. 단 HttpEtity.isRepeatable()=true 인 Entity에 한정된다.
|
||||
profiler.apache.httpclient4.entity=true
|
||||
|
||||
# entity를 언제 덤프할지 결정. ALWAYS or EXCEPTION 2가지
|
||||
profiler.apache.httpclient4.entity.dumptype=ALWAYS
|
||||
profiler.apache.httpclient4.entity.sampling.rate=1
|
||||
|
||||
profiler.apache.nio.httpclient4=true
|
||||
|
||||
|
||||
###########################################################
|
||||
# Ning Async HTTP Client #
|
||||
###########################################################
|
||||
profiler.ning.asynchttpclient=true
|
||||
profiler.ning.asynchttpclient.cookie=true
|
||||
profiler.ning.asynchttpclient.cookie.dumptype=ALWAYS
|
||||
profiler.ning.asynchttpclient.cookie.dumpsize=1024
|
||||
profiler.ning.asynchttpclient.cookie.sampling.rate=1
|
||||
profiler.ning.asynchttpclient.entity=true
|
||||
profiler.ning.asynchttpclient.entity.dumptype=ALWAYS
|
||||
profiler.ning.asynchttpclient.entity.dumpsize=1024
|
||||
profiler.ning.asynchttpclient.entity.sampling.rate=1
|
||||
profiler.ning.asynchttpclient.param=true
|
||||
profiler.ning.asynchttpclient.param.dumptype=ALWAYS
|
||||
profiler.ning.asynchttpclient.param.dumpsize=1024
|
||||
profiler.ning.asynchttpclient.param.sampling.rate=1
|
||||
|
||||
|
||||
###########################################################
|
||||
# LINE+ baseframework #
|
||||
###########################################################
|
||||
profiler.line.game.netty.param.dumpsize=512
|
||||
profiler.line.game.netty.entity.dumpsize=512
|
||||
|
||||
|
||||
###########################################################
|
||||
# Arcus #
|
||||
###########################################################
|
||||
profiler.arcus=true
|
||||
profiler.arcus.keytrace=true
|
||||
|
||||
|
||||
###########################################################
|
||||
# Memcached #
|
||||
###########################################################
|
||||
profiler.memcached=true
|
||||
profiler.memcached.keytrace=true
|
||||
|
||||
|
||||
###########################################################
|
||||
# ibatis #
|
||||
###########################################################
|
||||
profiler.orm.ibatis=true
|
||||
|
||||
|
||||
###########################################################
|
||||
# mybatis #
|
||||
###########################################################
|
||||
profiler.orm.mybatis=true
|
||||
|
||||
###########################################################
|
||||
# spring-beans
|
||||
###########################################################
|
||||
profiler.spring.beans=true
|
||||
profiler.spring.beans.name.pattern=ma.*, outer
|
||||
profiler.spring.beans.class.pattern=.*Morae
|
||||
profiler.spring.beans.annotation=org.springframework.stereotype.Component
|
||||
+9
-9
@@ -18,7 +18,7 @@ public class InterceptorRegistry {
|
||||
|
||||
private final AtomicInteger id = new AtomicInteger(0);
|
||||
private final StaticAroundInterceptor[] index;
|
||||
private final SimpleAroundInterceptor[] simpleIndex;
|
||||
private final SimpleInterceptor[] simpleIndex;
|
||||
|
||||
// private final ConcurrentMap<String, Integer> nameIndex = new ConcurrentHashMap<String, Integer>();
|
||||
|
||||
@@ -29,7 +29,7 @@ public class InterceptorRegistry {
|
||||
InterceptorRegistry(int max) {
|
||||
this.max = max;
|
||||
this.index = new StaticAroundInterceptor[max];
|
||||
this.simpleIndex = new SimpleAroundInterceptor[max];
|
||||
this.simpleIndex = new SimpleInterceptor[max];
|
||||
}
|
||||
|
||||
|
||||
@@ -51,7 +51,7 @@ public class InterceptorRegistry {
|
||||
return id.getAndIncrement();
|
||||
}
|
||||
|
||||
int addSimpleInterceptor0(SimpleAroundInterceptor interceptor) {
|
||||
int addSimpleInterceptor0(SimpleInterceptor interceptor) {
|
||||
if (interceptor == null) {
|
||||
return -1;
|
||||
}
|
||||
@@ -59,7 +59,7 @@ public class InterceptorRegistry {
|
||||
if (newId >= max) {
|
||||
throw new IndexOutOfBoundsException("size=" + index.length + " id=" + id);
|
||||
}
|
||||
|
||||
|
||||
this.simpleIndex[newId] = interceptor;
|
||||
// this.nameIndex.put(interceptor.getClass().getName(), newId);
|
||||
return newId;
|
||||
@@ -74,8 +74,8 @@ public class InterceptorRegistry {
|
||||
return interceptor;
|
||||
}
|
||||
|
||||
SimpleAroundInterceptor getSimpleInterceptor0(int key) {
|
||||
SimpleAroundInterceptor interceptor = simpleIndex[key];
|
||||
SimpleInterceptor getSimpleInterceptor0(int key) {
|
||||
SimpleInterceptor interceptor = simpleIndex[key];
|
||||
if (interceptor == null) {
|
||||
// 로직이 잘못되었을경우 에러가 발생하지 않도록 더미를 리턴.
|
||||
return DUMMY;
|
||||
@@ -109,7 +109,7 @@ public class InterceptorRegistry {
|
||||
|
||||
|
||||
public static Interceptor findInterceptor(int key) {
|
||||
SimpleAroundInterceptor simpleInterceptor = REGISTRY.getSimpleInterceptor0(key);
|
||||
SimpleInterceptor simpleInterceptor = REGISTRY.getSimpleInterceptor0(key);
|
||||
if (simpleInterceptor != null) {
|
||||
return simpleInterceptor;
|
||||
}
|
||||
@@ -124,12 +124,12 @@ public class InterceptorRegistry {
|
||||
return DUMMY;
|
||||
}
|
||||
|
||||
public static int addSimpleInterceptor(SimpleAroundInterceptor interceptor) {
|
||||
public static int addSimpleInterceptor(SimpleInterceptor interceptor) {
|
||||
return REGISTRY.addSimpleInterceptor0(interceptor);
|
||||
}
|
||||
|
||||
|
||||
public static SimpleAroundInterceptor getSimpleInterceptor(int key) {
|
||||
public static SimpleInterceptor getSimpleInterceptor(int key) {
|
||||
return REGISTRY.getSimpleInterceptor0(key);
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -3,6 +3,6 @@ package com.nhn.pinpoint.bootstrap.interceptor;
|
||||
/**
|
||||
* @author emeroad
|
||||
*/
|
||||
public interface SimpleAfterInterceptor extends Interceptor {
|
||||
public interface SimpleAfterInterceptor extends SimpleInterceptor {
|
||||
void after(Object target, Object[] args, Object result, Throwable throwable);
|
||||
}
|
||||
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
package com.nhn.pinpoint.bootstrap.interceptor;
|
||||
|
||||
public interface SimpleBeforeInterceptor extends Interceptor {
|
||||
public interface SimpleBeforeInterceptor extends SimpleInterceptor {
|
||||
void before(Object target, Object[] args);
|
||||
}
|
||||
|
||||
+5
@@ -0,0 +1,5 @@
|
||||
package com.nhn.pinpoint.bootstrap.interceptor;
|
||||
|
||||
public interface SimpleInterceptor extends Interceptor {
|
||||
|
||||
}
|
||||
+12
-3
@@ -5,12 +5,14 @@ import java.util.List;
|
||||
import com.nhn.pinpoint.bootstrap.instrument.InstrumentClass;
|
||||
import com.nhn.pinpoint.exception.PinpointException;
|
||||
|
||||
public class BasicClassEditor implements ClassEditor {
|
||||
public class BasicClassEditor implements DedicatedClassEditor {
|
||||
private final String targetClassName;
|
||||
private final List<MetadataInjector> metadataInjectors;
|
||||
private final List<InterceptorInjector> interceptorInjectors;
|
||||
|
||||
|
||||
public BasicClassEditor(List<MetadataInjector> metadataInjectors, List<InterceptorInjector> interceptorInjectors) {
|
||||
public BasicClassEditor(String targetClassName, List<MetadataInjector> metadataInjectors, List<InterceptorInjector> interceptorInjectors) {
|
||||
this.targetClassName = targetClassName;
|
||||
this.metadataInjectors = metadataInjectors;
|
||||
this.interceptorInjectors = interceptorInjectors;
|
||||
}
|
||||
@@ -28,7 +30,14 @@ public class BasicClassEditor implements ClassEditor {
|
||||
|
||||
return target.toBytecode();
|
||||
} catch (Throwable t) {
|
||||
throw new PinpointException("Fail to edit class", t);
|
||||
throw new PinpointException("Fail to edit class: " + targetClassName, t);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getTargetClassName() {
|
||||
return targetClassName;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
+25
-21
@@ -6,8 +6,6 @@ import java.util.List;
|
||||
import com.nhn.pinpoint.bootstrap.context.TraceContext;
|
||||
import com.nhn.pinpoint.bootstrap.instrument.ByteCodeInstrumentor;
|
||||
import com.nhn.pinpoint.bootstrap.instrument.MethodFilter;
|
||||
import com.nhn.pinpoint.bootstrap.interceptor.Interceptor;
|
||||
import com.nhn.pinpoint.bootstrap.interceptor.tracevalue.TraceValue;
|
||||
import com.nhn.pinpoint.bootstrap.plugin.MetadataInitializationStrategy.ByConstructor;
|
||||
|
||||
public class ClassEditorBuilder {
|
||||
@@ -17,6 +15,7 @@ public class ClassEditorBuilder {
|
||||
private final List<InterceptorBuilder> interceptorBuilders = new ArrayList<InterceptorBuilder>();
|
||||
private final List<MetadataBuilder> metadataBuilders = new ArrayList<MetadataBuilder>();
|
||||
|
||||
private String targetClassName;
|
||||
private Condition condition;
|
||||
|
||||
public ClassEditorBuilder(ByteCodeInstrumentor instrumentor, TraceContext traceContext) {
|
||||
@@ -24,13 +23,18 @@ public class ClassEditorBuilder {
|
||||
this.traceContext = traceContext;
|
||||
}
|
||||
|
||||
public ClassEditorBuilder editWhen(Condition condition) {
|
||||
public ClassEditorBuilder edit(String targetClassName) {
|
||||
this.targetClassName = targetClassName;
|
||||
return this;
|
||||
}
|
||||
|
||||
public ClassEditorBuilder when(Condition condition) {
|
||||
this.condition = condition;
|
||||
return this;
|
||||
}
|
||||
|
||||
public InterceptorBuilder intercept(String methodName, Class<?>... parameterTypes) {
|
||||
InterceptorBuilder interceptorBuilder = new InterceptorBuilder(methodName, parameterTypes, null);
|
||||
public InterceptorBuilder intercept(String methodName, String... parameterTypeNames) {
|
||||
InterceptorBuilder interceptorBuilder = new InterceptorBuilder(methodName, parameterTypeNames, null);
|
||||
interceptorBuilders.add(interceptorBuilder);
|
||||
return interceptorBuilder;
|
||||
}
|
||||
@@ -41,19 +45,19 @@ public class ClassEditorBuilder {
|
||||
return interceptorBuilder;
|
||||
}
|
||||
|
||||
public InterceptorBuilder interceptConstructor(Class<?>... parameterTypes) {
|
||||
InterceptorBuilder interceptorBuilder = new InterceptorBuilder(null, parameterTypes, null);
|
||||
public InterceptorBuilder interceptConstructor(String... parameterTypeNames) {
|
||||
InterceptorBuilder interceptorBuilder = new InterceptorBuilder(null, parameterTypeNames, null);
|
||||
interceptorBuilders.add(interceptorBuilder);
|
||||
return interceptorBuilder;
|
||||
}
|
||||
|
||||
public MetadataBuilder inject(Class<? extends TraceValue> metadataType) {
|
||||
MetadataBuilder metadataBuilder = new MetadataBuilder(metadataType);
|
||||
public MetadataBuilder inject(String metadataAccessorName) {
|
||||
MetadataBuilder metadataBuilder = new MetadataBuilder(metadataAccessorName);
|
||||
metadataBuilders.add(metadataBuilder);
|
||||
return metadataBuilder;
|
||||
}
|
||||
|
||||
public ClassEditor build() {
|
||||
public DedicatedClassEditor build() {
|
||||
List<MetadataInjector> metadataInjectors = new ArrayList<MetadataInjector>(metadataBuilders.size());
|
||||
|
||||
for (MetadataBuilder builder : metadataBuilders) {
|
||||
@@ -66,7 +70,7 @@ public class ClassEditorBuilder {
|
||||
interceptorInjectors.add(builder.build());
|
||||
}
|
||||
|
||||
ClassEditor editor = new BasicClassEditor(metadataInjectors, interceptorInjectors);
|
||||
DedicatedClassEditor editor = new BasicClassEditor(targetClassName, metadataInjectors, interceptorInjectors);
|
||||
|
||||
if (condition != null) {
|
||||
editor = new ConditionalClassEditor(condition, editor);
|
||||
@@ -80,16 +84,16 @@ public class ClassEditorBuilder {
|
||||
private final String[] parameterTypes;
|
||||
private final MethodFilter filter;
|
||||
|
||||
private Class<? extends Interceptor> interceptorClass;
|
||||
private String interceptorClassName;
|
||||
private Condition condition;
|
||||
private String scopeName;
|
||||
private Object[] constructorArguments;
|
||||
private ParameterExtractorFactory parameterExtractorFactory;
|
||||
private boolean singleton;
|
||||
|
||||
public InterceptorBuilder(String methodName, Class<?>[] parameterTypes, MethodFilter filter) {
|
||||
public InterceptorBuilder(String methodName, String[] parameterTypeNames, MethodFilter filter) {
|
||||
this.methodName = methodName;
|
||||
this.parameterTypes = TypeUtils.toClassNames(parameterTypes);
|
||||
this.parameterTypes = parameterTypeNames;
|
||||
this.filter = filter;
|
||||
}
|
||||
|
||||
@@ -98,8 +102,8 @@ public class ClassEditorBuilder {
|
||||
return this;
|
||||
}
|
||||
|
||||
public InterceptorBuilder with(Class<? extends Interceptor> interceptorClass) {
|
||||
this.interceptorClass = interceptorClass;
|
||||
public InterceptorBuilder with(String interceptorClassName) {
|
||||
this.interceptorClassName = interceptorClassName;
|
||||
return this;
|
||||
}
|
||||
|
||||
@@ -124,7 +128,7 @@ public class ClassEditorBuilder {
|
||||
}
|
||||
|
||||
private InterceptorInjector build() {
|
||||
InterceptorFactory interceptorFactory = new DefaultInterceptorFactory(instrumentor, traceContext, interceptorClass, constructorArguments, parameterExtractorFactory, scopeName);
|
||||
InterceptorFactory interceptorFactory = new DefaultInterceptorFactory(instrumentor, traceContext, interceptorClassName, constructorArguments, parameterExtractorFactory, scopeName);
|
||||
|
||||
InterceptorInjector injector;
|
||||
|
||||
@@ -145,11 +149,11 @@ public class ClassEditorBuilder {
|
||||
}
|
||||
|
||||
public class MetadataBuilder {
|
||||
private final Class<? extends TraceValue> metadataType;
|
||||
private final String metadataAccessorTypeName;
|
||||
private MetadataInitializationStrategy initializationStrategy;
|
||||
|
||||
public MetadataBuilder(Class<? extends TraceValue> metadataType) {
|
||||
this.metadataType = metadataType;
|
||||
public MetadataBuilder(String metadataAccessorTypeName) {
|
||||
this.metadataAccessorTypeName = metadataAccessorTypeName;
|
||||
}
|
||||
|
||||
public MetadataBuilder initializeWithDefaultConstructorOf(String className) {
|
||||
@@ -158,7 +162,7 @@ public class ClassEditorBuilder {
|
||||
}
|
||||
|
||||
private MetadataInjector build() {
|
||||
return new DefaultMetadataInjector(metadataType, initializationStrategy);
|
||||
return new DefaultMetadataInjector(metadataAccessorTypeName, initializationStrategy);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+8
-3
@@ -2,11 +2,11 @@ package com.nhn.pinpoint.bootstrap.plugin;
|
||||
|
||||
import com.nhn.pinpoint.bootstrap.instrument.InstrumentClass;
|
||||
|
||||
public class ConditionalClassEditor implements ClassEditor {
|
||||
public class ConditionalClassEditor implements DedicatedClassEditor {
|
||||
private final Condition condition;
|
||||
private final ClassEditor delegate;
|
||||
private final DedicatedClassEditor delegate;
|
||||
|
||||
public ConditionalClassEditor(Condition condition, ClassEditor delegate) {
|
||||
public ConditionalClassEditor(Condition condition, DedicatedClassEditor delegate) {
|
||||
this.condition = condition;
|
||||
this.delegate = delegate;
|
||||
}
|
||||
@@ -19,4 +19,9 @@ public class ConditionalClassEditor implements ClassEditor {
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getTargetClassName() {
|
||||
return delegate.getTargetClassName();
|
||||
}
|
||||
}
|
||||
|
||||
+14
-6
@@ -22,17 +22,17 @@ public class DefaultInterceptorFactory implements InterceptorFactory {
|
||||
private final ByteCodeInstrumentor instrumentor;
|
||||
private final TraceContext traceContext;
|
||||
|
||||
private final Class<? extends Interceptor> interceptorClass;
|
||||
private final String interceptorClassName;
|
||||
private final Object[] providedArguments;
|
||||
|
||||
private final ParameterExtractorFactory parameterExtractorFactory;
|
||||
private final String scopeName;
|
||||
|
||||
|
||||
public DefaultInterceptorFactory(ByteCodeInstrumentor instrumentor, TraceContext traceContext, Class<? extends Interceptor> interceptorClass, Object[] providedArguments, ParameterExtractorFactory parameterExtractorFactory, String scopeName) {
|
||||
public DefaultInterceptorFactory(ByteCodeInstrumentor instrumentor, TraceContext traceContext, String interceptorClassName, Object[] providedArguments, ParameterExtractorFactory parameterExtractorFactory, String scopeName) {
|
||||
this.instrumentor = instrumentor;
|
||||
this.traceContext = traceContext;
|
||||
this.interceptorClass = interceptorClass;
|
||||
this.interceptorClassName = interceptorClassName;
|
||||
this.providedArguments = providedArguments == null ? NO_ARGS : providedArguments;
|
||||
this.parameterExtractorFactory = parameterExtractorFactory;
|
||||
this.scopeName = scopeName;
|
||||
@@ -40,7 +40,7 @@ public class DefaultInterceptorFactory implements InterceptorFactory {
|
||||
|
||||
@Override
|
||||
public Interceptor getInterceptor(ClassLoader classLoader, InstrumentClass target, MethodInfo targetMethod) {
|
||||
Interceptor interceptor = createInstance(traceContext, classLoader, target, targetMethod);
|
||||
Interceptor interceptor = createInstance(classLoader, traceContext, target, targetMethod);
|
||||
|
||||
if (scopeName != null) {
|
||||
interceptor = wrapWithScope(interceptor);
|
||||
@@ -48,8 +48,16 @@ public class DefaultInterceptorFactory implements InterceptorFactory {
|
||||
|
||||
return interceptor;
|
||||
}
|
||||
|
||||
private Interceptor createInstance(TraceContext traceContext, ClassLoader classLoader, InstrumentClass target, MethodInfo targetMethod) {
|
||||
|
||||
private Interceptor createInstance(ClassLoader classLoader, TraceContext traceContext, InstrumentClass target, MethodInfo targetMethod) {
|
||||
Class<?> interceptorClass;
|
||||
|
||||
try {
|
||||
interceptorClass = classLoader.loadClass(interceptorClassName);
|
||||
} catch (ClassNotFoundException e) {
|
||||
throw new PinpointException("Cannot load interceptor class: " + interceptorClassName, e);
|
||||
}
|
||||
|
||||
Constructor<?>[] constructors = interceptorClass.getConstructors();
|
||||
Arrays.sort(constructors, CONSTRUCTOR_COMPARATOR);
|
||||
|
||||
|
||||
+21
-6
@@ -4,27 +4,42 @@ import com.nhn.pinpoint.bootstrap.instrument.InstrumentClass;
|
||||
import com.nhn.pinpoint.bootstrap.instrument.InstrumentException;
|
||||
import com.nhn.pinpoint.bootstrap.interceptor.tracevalue.TraceValue;
|
||||
import com.nhn.pinpoint.bootstrap.plugin.MetadataInitializationStrategy.ByConstructor;
|
||||
import com.nhn.pinpoint.exception.PinpointException;
|
||||
|
||||
public class DefaultMetadataInjector implements MetadataInjector {
|
||||
|
||||
private final Class<? extends TraceValue> metadataType;
|
||||
private final String metadataAccessorTypeName;
|
||||
private final MetadataInitializationStrategy strategy;
|
||||
|
||||
public DefaultMetadataInjector(Class<? extends TraceValue> metadataType, MetadataInitializationStrategy strategy) {
|
||||
this.metadataType = metadataType;
|
||||
public DefaultMetadataInjector(String metadataAccessorTypeName, MetadataInitializationStrategy strategy) {
|
||||
this.metadataAccessorTypeName = metadataAccessorTypeName;
|
||||
this.strategy = strategy;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public void inject(ClassLoader classLoader, InstrumentClass target) throws InstrumentException {
|
||||
Class<?> type;
|
||||
try {
|
||||
type = classLoader.loadClass(metadataAccessorTypeName);
|
||||
} catch (ClassNotFoundException e) {
|
||||
throw new PinpointException("Fail to load metadata accessor: " + metadataAccessorTypeName, e);
|
||||
}
|
||||
|
||||
if (!TraceValue.class.isAssignableFrom(type)) {
|
||||
throw new PinpointException("Given type " + metadataAccessorTypeName + " is not a subtype of TraceValue");
|
||||
}
|
||||
|
||||
Class<? extends TraceValue> metadataAccessorType = (Class<? extends TraceValue>)type;
|
||||
|
||||
if (strategy == null) {
|
||||
target.addTraceValue(metadataType);
|
||||
target.addTraceValue(metadataAccessorType);
|
||||
} else {
|
||||
if (strategy instanceof ByConstructor) {
|
||||
String javaExpression = "new " + ((ByConstructor)strategy).getClassName() + "();";
|
||||
target.addTraceValue(metadataType, javaExpression);
|
||||
target.addTraceValue(metadataAccessorType, javaExpression);
|
||||
} else {
|
||||
throw new IllegalArgumentException("Unsupported strategy: " + strategy);
|
||||
throw new PinpointException("Unsupported strategy: " + strategy);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,5 +3,5 @@ package com.nhn.pinpoint.bootstrap.plugin;
|
||||
import java.util.List;
|
||||
|
||||
public interface ProfilerPlugin {
|
||||
public List<ClassEditorFactoryMapping> getClassEditorMappings(ProfilerPluginContext context);
|
||||
public List<ClassEditor> getClassEditors(ProfilerPluginContext context);
|
||||
}
|
||||
|
||||
+4
-3
@@ -1,13 +1,14 @@
|
||||
package com.nhn.pinpoint.bootstrap.interceptor;
|
||||
|
||||
import com.nhn.pinpoint.bootstrap.context.RecordableTrace;
|
||||
import com.nhn.pinpoint.bootstrap.context.Trace;
|
||||
import static org.mockito.Mockito.*;
|
||||
import junit.framework.Assert;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import static org.mockito.Mockito.*;
|
||||
import com.nhn.pinpoint.bootstrap.context.RecordableTrace;
|
||||
import com.nhn.pinpoint.bootstrap.context.Trace;
|
||||
|
||||
|
||||
public class SpanSimpleAroundInterceptorTest {
|
||||
|
||||
+2
-2
@@ -40,8 +40,8 @@ public class ClassEditorBuilderTest {
|
||||
|
||||
ProfilerPluginContext helper = new ProfilerPluginContext(instrumentor, traceContext);
|
||||
ClassEditorBuilder builder = helper.newClassEditorBuilder();
|
||||
builder.intercept(methodName, parameterTypes).with(TestInterceptor.class).constructedWith("provided").in(scopeName);
|
||||
builder.inject(TestMetadata.class).initializeWithDefaultConstructorOf("java.util.HashMap");
|
||||
builder.intercept(methodName, parameterTypeNames).with("com.nhn.pinpoint.bootstrap.plugin.TestInterceptor").constructedWith("provided").in(scopeName);
|
||||
builder.inject("com.nhn.pinpoint.bootstrap.plugin.ClassEditorBuilderTest.TestMetadata").initializeWithDefaultConstructorOf("java.util.HashMap");
|
||||
ClassEditor editor = builder.build();
|
||||
|
||||
editor.edit(classLoader, aClass);
|
||||
|
||||
+14
-14
@@ -39,7 +39,7 @@ public class DefaultInterceptorFactoryTest {
|
||||
|
||||
@Test
|
||||
public void test0() throws Exception {
|
||||
DefaultInterceptorFactory factory = new DefaultInterceptorFactory(instrumentor, traceContext, TestInterceptor0.class, null, null, null);
|
||||
DefaultInterceptorFactory factory = new DefaultInterceptorFactory(instrumentor, traceContext, "com.nhn.pinpoint.bootstrap.plugin.TestInterceptors.TestInterceptor0", null, null, null);
|
||||
Interceptor interceptor = factory.getInterceptor(getClass().getClassLoader(), aClass, aMethod);
|
||||
|
||||
assertEquals(TestInterceptor0.class, interceptor.getClass());
|
||||
@@ -49,7 +49,7 @@ public class DefaultInterceptorFactoryTest {
|
||||
public void test1() throws Exception {
|
||||
Object[] args = new Object[] { "arg0" };
|
||||
|
||||
DefaultInterceptorFactory factory = new DefaultInterceptorFactory(instrumentor, traceContext, TestInterceptor0.class, args, null, null);
|
||||
DefaultInterceptorFactory factory = new DefaultInterceptorFactory(instrumentor, traceContext, "com.nhn.pinpoint.bootstrap.plugin.TestInterceptors.TestInterceptor0", args, null, null);
|
||||
Interceptor interceptor = factory.getInterceptor(getClass().getClassLoader(), aClass, aMethod);
|
||||
|
||||
assertEquals(TestInterceptor0.class, interceptor.getClass());
|
||||
@@ -60,7 +60,7 @@ public class DefaultInterceptorFactoryTest {
|
||||
public void test2() throws Exception {
|
||||
Object[] args = new Object[] { 1 };
|
||||
|
||||
DefaultInterceptorFactory factory = new DefaultInterceptorFactory(instrumentor, traceContext, TestInterceptor0.class, args, null, null);
|
||||
DefaultInterceptorFactory factory = new DefaultInterceptorFactory(instrumentor, traceContext, "com.nhn.pinpoint.bootstrap.plugin.TestInterceptors.TestInterceptor0", args, null, null);
|
||||
factory.getInterceptor(getClass().getClassLoader(), aClass, aMethod);
|
||||
}
|
||||
|
||||
@@ -68,7 +68,7 @@ public class DefaultInterceptorFactoryTest {
|
||||
public void test3() throws Exception {
|
||||
Object[] args = new Object[] { "arg0", (byte)1, (short)2, (float)3.0 };
|
||||
|
||||
DefaultInterceptorFactory factory = new DefaultInterceptorFactory(instrumentor, traceContext, TestInterceptor1.class, args, null, null);
|
||||
DefaultInterceptorFactory factory = new DefaultInterceptorFactory(instrumentor, traceContext, "com.nhn.pinpoint.bootstrap.plugin.TestInterceptors.TestInterceptor1", args, null, null);
|
||||
Interceptor interceptor = factory.getInterceptor(getClass().getClassLoader(), aClass, aMethod);
|
||||
|
||||
assertEquals(TestInterceptor1.class, interceptor.getClass());
|
||||
@@ -82,7 +82,7 @@ public class DefaultInterceptorFactoryTest {
|
||||
public void test4() throws Exception {
|
||||
Object[] args = new Object[] { (byte)1, (short)2, (float)3.0, "arg0" };
|
||||
|
||||
DefaultInterceptorFactory factory = new DefaultInterceptorFactory(instrumentor, traceContext, TestInterceptor1.class, args, null, null);
|
||||
DefaultInterceptorFactory factory = new DefaultInterceptorFactory(instrumentor, traceContext, "com.nhn.pinpoint.bootstrap.plugin.TestInterceptors.TestInterceptor1", args, null, null);
|
||||
Interceptor interceptor = factory.getInterceptor(getClass().getClassLoader(), aClass, aMethod);
|
||||
|
||||
assertEquals(TestInterceptor1.class, interceptor.getClass());
|
||||
@@ -96,7 +96,7 @@ public class DefaultInterceptorFactoryTest {
|
||||
public void test5() throws Exception {
|
||||
Object[] args = new Object[] { (short)2, (float)3.0, "arg0", (byte)1 };
|
||||
|
||||
DefaultInterceptorFactory factory = new DefaultInterceptorFactory(instrumentor, traceContext, TestInterceptor1.class, args, null, null);
|
||||
DefaultInterceptorFactory factory = new DefaultInterceptorFactory(instrumentor, traceContext, "com.nhn.pinpoint.bootstrap.plugin.TestInterceptors.TestInterceptor1", args, null, null);
|
||||
Interceptor interceptor = factory.getInterceptor(getClass().getClassLoader(), aClass, aMethod);
|
||||
|
||||
assertEquals(TestInterceptor1.class, interceptor.getClass());
|
||||
@@ -110,7 +110,7 @@ public class DefaultInterceptorFactoryTest {
|
||||
public void test6() throws Exception {
|
||||
Object[] args = new Object[] { (float)3.0, (short)2, (byte)1, "arg0" };
|
||||
|
||||
DefaultInterceptorFactory factory = new DefaultInterceptorFactory(instrumentor, traceContext, TestInterceptor1.class, args, null, null);
|
||||
DefaultInterceptorFactory factory = new DefaultInterceptorFactory(instrumentor, traceContext, "com.nhn.pinpoint.bootstrap.plugin.TestInterceptors.TestInterceptor1", args, null, null);
|
||||
Interceptor interceptor = factory.getInterceptor(getClass().getClassLoader(), aClass, aMethod);
|
||||
|
||||
assertEquals(TestInterceptor1.class, interceptor.getClass());
|
||||
@@ -124,13 +124,13 @@ public class DefaultInterceptorFactoryTest {
|
||||
public void test7() throws Exception {
|
||||
Object[] args = new Object[] { (double)3.0, (short)2, (byte)1, "arg0" };
|
||||
|
||||
DefaultInterceptorFactory factory = new DefaultInterceptorFactory(instrumentor, traceContext, TestInterceptor1.class, args, null, null);
|
||||
DefaultInterceptorFactory factory = new DefaultInterceptorFactory(instrumentor, traceContext, "com.nhn.pinpoint.bootstrap.plugin.TestInterceptors.TestInterceptor1", args, null, null);
|
||||
factory.getInterceptor(getClass().getClassLoader(), aClass, aMethod);
|
||||
}
|
||||
|
||||
@Test(expected=PinpointException.class)
|
||||
public void test8() throws Exception {
|
||||
DefaultInterceptorFactory factory = new DefaultInterceptorFactory(instrumentor, traceContext, TestInterceptor1.class, null, null, null);
|
||||
DefaultInterceptorFactory factory = new DefaultInterceptorFactory(instrumentor, traceContext, "com.nhn.pinpoint.bootstrap.plugin.TestInterceptors.TestInterceptor1", null, null, null);
|
||||
factory.getInterceptor(getClass().getClassLoader(), aClass, aMethod);
|
||||
}
|
||||
|
||||
@@ -138,7 +138,7 @@ public class DefaultInterceptorFactoryTest {
|
||||
public void test9() throws Exception {
|
||||
Object[] args = new Object[] { "arg0", 1, 2.0, true, 3L };
|
||||
|
||||
DefaultInterceptorFactory factory = new DefaultInterceptorFactory(instrumentor, traceContext, TestInterceptor2.class, args, extractorFactory, null);
|
||||
DefaultInterceptorFactory factory = new DefaultInterceptorFactory(instrumentor, traceContext, "com.nhn.pinpoint.bootstrap.plugin.TestInterceptors.TestInterceptor2", args, extractorFactory, null);
|
||||
Interceptor interceptor = factory.getInterceptor(getClass().getClassLoader(), aClass, aMethod);
|
||||
|
||||
assertEquals(TestInterceptor2.class, interceptor.getClass());
|
||||
@@ -156,7 +156,7 @@ public class DefaultInterceptorFactoryTest {
|
||||
public void test10() throws Exception {
|
||||
Object[] args = new Object[] { "arg0", 1, 2.0 };
|
||||
|
||||
DefaultInterceptorFactory factory = new DefaultInterceptorFactory(instrumentor, traceContext, TestInterceptor2.class, args, extractorFactory, null);
|
||||
DefaultInterceptorFactory factory = new DefaultInterceptorFactory(instrumentor, traceContext, "com.nhn.pinpoint.bootstrap.plugin.TestInterceptors.TestInterceptor2", args, extractorFactory, null);
|
||||
Interceptor interceptor = factory.getInterceptor(getClass().getClassLoader(), aClass, aMethod);
|
||||
|
||||
assertEquals(TestInterceptor2.class, interceptor.getClass());
|
||||
@@ -174,7 +174,7 @@ public class DefaultInterceptorFactoryTest {
|
||||
public void test11() throws Exception {
|
||||
Object[] args = new Object[] { "arg0", 1 };
|
||||
|
||||
DefaultInterceptorFactory factory = new DefaultInterceptorFactory(instrumentor, traceContext, TestInterceptor2.class, args, extractorFactory, null);
|
||||
DefaultInterceptorFactory factory = new DefaultInterceptorFactory(instrumentor, traceContext, "com.nhn.pinpoint.bootstrap.plugin.TestInterceptors.TestInterceptor2", args, extractorFactory, null);
|
||||
Interceptor interceptor = factory.getInterceptor(getClass().getClassLoader(), aClass, aMethod);
|
||||
|
||||
assertEquals(TestInterceptor2.class, interceptor.getClass());
|
||||
@@ -190,7 +190,7 @@ public class DefaultInterceptorFactoryTest {
|
||||
|
||||
@Test
|
||||
public void test12() throws Exception {
|
||||
DefaultInterceptorFactory factory = new DefaultInterceptorFactory(instrumentor, traceContext, TestInterceptor2.class, null, extractorFactory, null);
|
||||
DefaultInterceptorFactory factory = new DefaultInterceptorFactory(instrumentor, traceContext, "com.nhn.pinpoint.bootstrap.plugin.TestInterceptors.TestInterceptor2", null, extractorFactory, null);
|
||||
Interceptor interceptor = factory.getInterceptor(getClass().getClassLoader(), aClass, aMethod);
|
||||
|
||||
assertEquals(TestInterceptor2.class, interceptor.getClass());
|
||||
@@ -206,7 +206,7 @@ public class DefaultInterceptorFactoryTest {
|
||||
|
||||
@Test
|
||||
public void test13() throws Exception {
|
||||
DefaultInterceptorFactory factory = new DefaultInterceptorFactory(instrumentor, traceContext, TestInterceptor2.class, null, null, null);
|
||||
DefaultInterceptorFactory factory = new DefaultInterceptorFactory(instrumentor, traceContext, "com.nhn.pinpoint.bootstrap.plugin.TestInterceptors.TestInterceptor2", null, null, null);
|
||||
Interceptor interceptor = factory.getInterceptor(getClass().getClassLoader(), aClass, aMethod);
|
||||
|
||||
assertEquals(TestInterceptor2.class, interceptor.getClass());
|
||||
|
||||
@@ -1,2 +0,0 @@
|
||||
/.settings/
|
||||
/.project
|
||||
@@ -1,22 +0,0 @@
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<parent>
|
||||
<groupId>com.nhn.pinpoint</groupId>
|
||||
<artifactId>pom</artifactId>
|
||||
<version>1.0.4-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>pinpoint-plugins</artifactId>
|
||||
<name>pinpoint-plugins</name>
|
||||
<packaging>pom</packaging>
|
||||
|
||||
<modules>
|
||||
<module>arcus</module>
|
||||
</modules>
|
||||
<dependencies>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
</build>
|
||||
</project>
|
||||
@@ -68,13 +68,20 @@
|
||||
<module>profiler</module>
|
||||
<module>profiler-optional</module>
|
||||
<module>rpc</module>
|
||||
<module>test</module>
|
||||
<module>thrift</module>
|
||||
<module>web</module>
|
||||
|
||||
<!-- plugins -->
|
||||
<module>arcus</module>
|
||||
</modules>
|
||||
|
||||
<properties>
|
||||
<pinpoint-version>1.0.4-SNAPSHOT</pinpoint-version>
|
||||
|
||||
|
||||
<pinpoint.agent.directory>build/pinpoint-agent</pinpoint.agent.directory>
|
||||
<pinpoint.agent.plugin.directory>${pinpoint.agent.directory}/plugin</pinpoint.agent.plugin.directory>
|
||||
|
||||
<encoding>UTF-8</encoding>
|
||||
<jdk.version>1.6</jdk.version>
|
||||
<slf4j.version>1.7.5</slf4j.version>
|
||||
@@ -668,19 +675,6 @@
|
||||
<artifactId>maven-antrun-plugin</artifactId>
|
||||
<version>1.7</version>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>com.nhncorp.maven</groupId>
|
||||
<artifactId>maven-revision-plugin</artifactId>
|
||||
<version>1.0.0</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<phase>compile</phase>
|
||||
<goals>
|
||||
<goal>create</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-surefire-plugin</artifactId>
|
||||
@@ -724,7 +718,7 @@
|
||||
<artifactId>maven-klocwork-plugin</artifactId>
|
||||
<version>1.0.0</version>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
<reporting>
|
||||
|
||||
+1
-1
@@ -12,7 +12,7 @@
|
||||
<packaging>jar</packaging>
|
||||
|
||||
<properties>
|
||||
<pinpiont-agent-dir>${basedir}/target/pinpoint-agent/</pinpiont-agent-dir>
|
||||
<pinpiont-agent-dir>../${pinpoint.agent.directory}</pinpiont-agent-dir>
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
|
||||
+22
-4
@@ -11,7 +11,8 @@ import org.slf4j.LoggerFactory;
|
||||
|
||||
import com.nhn.pinpoint.bootstrap.config.ProfilerConfig;
|
||||
import com.nhn.pinpoint.bootstrap.instrument.ByteCodeInstrumentor;
|
||||
import com.nhn.pinpoint.bootstrap.plugin.ClassEditorFactoryMapping;
|
||||
import com.nhn.pinpoint.bootstrap.plugin.ClassEditor;
|
||||
import com.nhn.pinpoint.bootstrap.plugin.DedicatedClassEditor;
|
||||
import com.nhn.pinpoint.bootstrap.plugin.PluginClassLoaderFactory;
|
||||
import com.nhn.pinpoint.bootstrap.plugin.ProfilerPlugin;
|
||||
import com.nhn.pinpoint.bootstrap.plugin.ProfilerPluginContext;
|
||||
@@ -63,13 +64,22 @@ public class ClassFileTransformerDispatcher implements ClassFileTransformer {
|
||||
|
||||
@Override
|
||||
public byte[] transform(ClassLoader classLoader, String className, Class<?> classBeingRedefined, ProtectionDomain protectionDomain, byte[] classFileBuffer) throws IllegalClassFormatException {
|
||||
|
||||
if (className.contains("CacheManager")) {
|
||||
logger.debug("Start CacheManager");
|
||||
}
|
||||
|
||||
if (skipFilter.doFilter(classLoader, className, classBeingRedefined, protectionDomain, classFileBuffer)) {
|
||||
if (className.equals("net/spy/memcached/CacheManager")) {
|
||||
logger.debug("skip CacheManager");
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
AbstractModifier findModifier = this.modifierRegistry.findModifier(className);
|
||||
if (findModifier == null) {
|
||||
if (className.equals("net/spy/memcached/CacheManager")) {
|
||||
logger.debug("no modifier for CacheManager");
|
||||
}
|
||||
// TODO : 디버그 용도로 추가함
|
||||
// TODO : modifier가 중복 적용되면 어떻게 되지???
|
||||
if (this.profilerConfig.getProfilableClassFilter().filter(className)) {
|
||||
@@ -171,8 +181,16 @@ public class ClassFileTransformerDispatcher implements ClassFileTransformer {
|
||||
ProfilerPluginContext pluginContext = new ProfilerPluginContext(byteCodeInstrumentor, agent.getTraceContext());
|
||||
|
||||
for (ProfilerPlugin plugin : plugins) {
|
||||
for (ClassEditorFactoryMapping mapping : plugin.getClassEditorMappings(pluginContext)) {
|
||||
modifierRepository.addModifier(new ClassEditorAdaptor(byteCodeInstrumentor, agent, mapping, pluginContext, classLoaderFactory));
|
||||
logger.info("Loading plugin: {}", plugin.getClass().getName());
|
||||
|
||||
for (ClassEditor editor : plugin.getClassEditors(pluginContext)) {
|
||||
if (editor instanceof DedicatedClassEditor) {
|
||||
DedicatedClassEditor dedicated = (DedicatedClassEditor)editor;
|
||||
logger.info("Registering class editor {} for {} ", dedicated.getClass().getName(), dedicated.getTargetClassName());
|
||||
modifierRepository.addModifier(new ClassEditorAdaptor(byteCodeInstrumentor, agent, dedicated, classLoaderFactory));
|
||||
} else {
|
||||
logger.warn("Ignore class editor {}", editor.getClass().getName());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -115,12 +115,6 @@ public class DefaultAgent implements Agent {
|
||||
logger.info("DefaultAgent classLoader:{}", this.getClass().getClassLoader());
|
||||
}
|
||||
|
||||
ClassFileRetransformer retransformer = new ClassFileRetransformer(instrumentation);
|
||||
instrumentation.addTransformer(retransformer, true);
|
||||
this.classFileTransformer = new ClassFileTransformerDispatcher(this, byteCodeInstrumentor, retransformer);
|
||||
instrumentation.addTransformer(this.classFileTransformer);
|
||||
|
||||
|
||||
final AgentInformationFactory agentInformationFactory = new AgentInformationFactory();
|
||||
this.agentInformation = agentInformationFactory.createAgentInformation(typeResolver.getServerType());
|
||||
logger.info("agentInformation:{}", agentInformation);
|
||||
@@ -145,6 +139,13 @@ public class DefaultAgent implements Agent {
|
||||
|
||||
// JVM 통계 등을 주기적으로 수집하여 collector에 전송하는 monitor를 초기화한다.
|
||||
this.agentStatMonitor = new AgentStatMonitor(this.statDataSender, this.agentInformation.getAgentId(), this.agentInformation.getStartTime());
|
||||
|
||||
|
||||
ClassFileRetransformer retransformer = new ClassFileRetransformer(instrumentation);
|
||||
instrumentation.addTransformer(retransformer, true);
|
||||
this.classFileTransformer = new ClassFileTransformerDispatcher(this, byteCodeInstrumentor, retransformer);
|
||||
instrumentation.addTransformer(this.classFileTransformer);
|
||||
|
||||
|
||||
preLoadClass();
|
||||
|
||||
|
||||
+54
-43
@@ -5,13 +5,12 @@ import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import com.nhn.pinpoint.bootstrap.context.TraceContext;
|
||||
import com.nhn.pinpoint.bootstrap.interceptor.*;
|
||||
import javassist.*;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import com.nhn.pinpoint.bootstrap.context.TraceContext;
|
||||
import com.nhn.pinpoint.bootstrap.instrument.InstrumentClass;
|
||||
import com.nhn.pinpoint.bootstrap.instrument.InstrumentException;
|
||||
import com.nhn.pinpoint.bootstrap.instrument.MethodFilter;
|
||||
@@ -19,6 +18,17 @@ import com.nhn.pinpoint.bootstrap.instrument.MethodInfo;
|
||||
import com.nhn.pinpoint.bootstrap.instrument.NotFoundInstrumentException;
|
||||
import com.nhn.pinpoint.bootstrap.instrument.Scope;
|
||||
import com.nhn.pinpoint.bootstrap.instrument.Type;
|
||||
import com.nhn.pinpoint.bootstrap.interceptor.ByteCodeMethodDescriptorSupport;
|
||||
import com.nhn.pinpoint.bootstrap.interceptor.Interceptor;
|
||||
import com.nhn.pinpoint.bootstrap.interceptor.InterceptorRegistry;
|
||||
import com.nhn.pinpoint.bootstrap.interceptor.LoggingInterceptor;
|
||||
import com.nhn.pinpoint.bootstrap.interceptor.MethodDescriptor;
|
||||
import com.nhn.pinpoint.bootstrap.interceptor.SimpleAfterInterceptor;
|
||||
import com.nhn.pinpoint.bootstrap.interceptor.SimpleAroundInterceptor;
|
||||
import com.nhn.pinpoint.bootstrap.interceptor.SimpleBeforeInterceptor;
|
||||
import com.nhn.pinpoint.bootstrap.interceptor.SimpleInterceptor;
|
||||
import com.nhn.pinpoint.bootstrap.interceptor.StaticAroundInterceptor;
|
||||
import com.nhn.pinpoint.bootstrap.interceptor.TraceContextSupport;
|
||||
import com.nhn.pinpoint.bootstrap.interceptor.tracevalue.TraceValue;
|
||||
import com.nhn.pinpoint.profiler.interceptor.DebugScopeDelegateSimpleInterceptor;
|
||||
import com.nhn.pinpoint.profiler.interceptor.DebugScopeDelegateStaticInterceptor;
|
||||
@@ -283,16 +293,17 @@ public class JavaAssistClass implements InstrumentClass {
|
||||
throw new IllegalArgumentException("interceptor is null");
|
||||
}
|
||||
final CtConstructor behavior = getCtConstructor(args);
|
||||
return addInterceptor0(behavior, null, interceptor, NOT_DEFINE_INTERCEPTOR_ID, Type.around, false);
|
||||
return addInterceptor0(behavior, null, interceptor, NOT_DEFINE_INTERCEPTOR_ID, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
// TODO remove parameter type
|
||||
public int addConstructorInterceptor(String[] args, Interceptor interceptor, Type type) throws InstrumentException, NotFoundInstrumentException {
|
||||
if (interceptor == null) {
|
||||
throw new IllegalArgumentException("interceptor is null");
|
||||
}
|
||||
final CtConstructor behavior = getCtConstructor(args);
|
||||
return addInterceptor0(behavior, null, interceptor, NOT_DEFINE_INTERCEPTOR_ID, type, false);
|
||||
return addInterceptor0(behavior, null, interceptor, NOT_DEFINE_INTERCEPTOR_ID, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -301,6 +312,7 @@ public class JavaAssistClass implements InstrumentClass {
|
||||
}
|
||||
|
||||
@Override
|
||||
// TODO remove parameter type
|
||||
public int addAllConstructorInterceptor(Interceptor interceptor, Type type) throws InstrumentException, NotFoundInstrumentException {
|
||||
if (interceptor == null) {
|
||||
throw new IllegalArgumentException("interceptor is null");
|
||||
@@ -312,11 +324,11 @@ public class JavaAssistClass implements InstrumentClass {
|
||||
}
|
||||
int interceptorId = 0;
|
||||
if (length > 0) {
|
||||
interceptorId = addInterceptor0(constructorList[0], null, interceptor, NOT_DEFINE_INTERCEPTOR_ID, type, false);
|
||||
interceptorId = addInterceptor0(constructorList[0], null, interceptor, NOT_DEFINE_INTERCEPTOR_ID, false);
|
||||
}
|
||||
if (length > 1) {
|
||||
for (int i = 1; i< length; i++) {
|
||||
addInterceptor0(constructorList[i], null, null, interceptorId, Type.around, false);
|
||||
addInterceptor0(constructorList[i], null, null, interceptorId, false);
|
||||
}
|
||||
}
|
||||
return interceptorId;
|
||||
@@ -329,16 +341,17 @@ public class JavaAssistClass implements InstrumentClass {
|
||||
throw new IllegalArgumentException("interceptor is null");
|
||||
}
|
||||
final CtBehavior behavior = getMethod(methodName, args);
|
||||
return addInterceptor0(behavior, methodName, interceptor, NOT_DEFINE_INTERCEPTOR_ID, Type.around, true);
|
||||
return addInterceptor0(behavior, methodName, interceptor, NOT_DEFINE_INTERCEPTOR_ID, true);
|
||||
}
|
||||
|
||||
@Override
|
||||
// TODO remove parameter type
|
||||
public int addInterceptorCallByContextClassLoader(String methodName, String[] args, Interceptor interceptor, Type type) throws InstrumentException, NotFoundInstrumentException {
|
||||
if (interceptor == null) {
|
||||
throw new IllegalArgumentException("interceptor is null");
|
||||
}
|
||||
final CtBehavior behavior = getMethod(methodName, args);
|
||||
return addInterceptor0(behavior, methodName, interceptor, NOT_DEFINE_INTERCEPTOR_ID, type, true);
|
||||
return addInterceptor0(behavior, methodName, interceptor, NOT_DEFINE_INTERCEPTOR_ID, true);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -350,7 +363,7 @@ public class JavaAssistClass implements InstrumentClass {
|
||||
throw new IllegalArgumentException("interceptor is null");
|
||||
}
|
||||
final CtBehavior behavior = getMethod(methodName, args);
|
||||
return addInterceptor0(behavior, methodName, interceptor, NOT_DEFINE_INTERCEPTOR_ID, Type.around, false);
|
||||
return addInterceptor0(behavior, methodName, interceptor, NOT_DEFINE_INTERCEPTOR_ID, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -431,33 +444,35 @@ public class JavaAssistClass implements InstrumentClass {
|
||||
@Override
|
||||
public int reuseInterceptor(String methodName, String[] args, int interceptorId) throws InstrumentException, NotFoundInstrumentException {
|
||||
final CtBehavior behavior = getMethod(methodName, args);
|
||||
return addInterceptor0(behavior, methodName, null, interceptorId, Type.around, false);
|
||||
return addInterceptor0(behavior, methodName, null, interceptorId, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
// TODO remove parameter type
|
||||
public int reuseInterceptor(String methodName, String[] args, int interceptorId, Type type) throws InstrumentException, NotFoundInstrumentException {
|
||||
final CtBehavior behavior = getMethod(methodName, args);
|
||||
return addInterceptor0(behavior, methodName, null, interceptorId, type, false);
|
||||
return addInterceptor0(behavior, methodName, null, interceptorId, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
// TODO remove parameter type
|
||||
public int addInterceptor(String methodName, String[] args, Interceptor interceptor, Type type) throws InstrumentException, NotFoundInstrumentException {
|
||||
if (interceptor == null) {
|
||||
throw new IllegalArgumentException("interceptor is null");
|
||||
}
|
||||
final CtBehavior behavior = getMethod(methodName, args);
|
||||
return addInterceptor0(behavior, methodName, interceptor, NOT_DEFINE_INTERCEPTOR_ID, type, false);
|
||||
return addInterceptor0(behavior, methodName, interceptor, NOT_DEFINE_INTERCEPTOR_ID, false);
|
||||
}
|
||||
|
||||
|
||||
private int addInterceptor0(CtBehavior behavior, String methodName, Interceptor interceptor, int interceptorId, Type type, boolean useContextClassLoader) throws InstrumentException, NotFoundInstrumentException {
|
||||
private int addInterceptor0(CtBehavior behavior, String methodName, Interceptor interceptor, int interceptorId, boolean useContextClassLoader) throws InstrumentException, NotFoundInstrumentException {
|
||||
try {
|
||||
if (interceptor != null) {
|
||||
if(interceptor instanceof StaticAroundInterceptor) {
|
||||
StaticAroundInterceptor staticAroundInterceptor = (StaticAroundInterceptor) interceptor;
|
||||
interceptorId = InterceptorRegistry.addInterceptor(staticAroundInterceptor);
|
||||
} else if(interceptor instanceof SimpleAroundInterceptor) {
|
||||
SimpleAroundInterceptor simpleAroundInterceptor = (SimpleAroundInterceptor) interceptor;
|
||||
} else if(interceptor instanceof SimpleInterceptor) {
|
||||
SimpleInterceptor simpleAroundInterceptor = (SimpleInterceptor) interceptor;
|
||||
interceptorId = InterceptorRegistry.addSimpleInterceptor(simpleAroundInterceptor);
|
||||
} else {
|
||||
throw new InstrumentException("unsupported Interceptor Type:" + interceptor);
|
||||
@@ -469,32 +484,28 @@ public class JavaAssistClass implements InstrumentClass {
|
||||
}
|
||||
// 이제는 aroundType 인터셉터만 받고 코드 인젝션을 별도 type으로 받아야 함.
|
||||
if (interceptor instanceof StaticAroundInterceptor) {
|
||||
switch (type) {
|
||||
case around:
|
||||
// switch (type) {
|
||||
// case around:
|
||||
addStaticAroundInterceptor(methodName, interceptorId, behavior, useContextClassLoader);
|
||||
break;
|
||||
case before:
|
||||
addStaticBeforeInterceptor(methodName, interceptorId, behavior, useContextClassLoader);
|
||||
break;
|
||||
case after:
|
||||
addStaticAfterInterceptor(methodName, interceptorId, behavior, useContextClassLoader);
|
||||
break;
|
||||
default:
|
||||
throw new UnsupportedOperationException("unsupport type");
|
||||
}
|
||||
} else if(interceptor instanceof SimpleAroundInterceptor) {
|
||||
switch (type) {
|
||||
case around:
|
||||
addSimpleAroundInterceptor(methodName, interceptorId, behavior, useContextClassLoader);
|
||||
break;
|
||||
case before:
|
||||
addSimpleBeforeInterceptor(methodName, interceptorId, behavior, useContextClassLoader);
|
||||
break;
|
||||
case after:
|
||||
addSimpleAfterInterceptor(methodName, interceptorId, behavior, useContextClassLoader);
|
||||
break;
|
||||
default:
|
||||
throw new UnsupportedOperationException("unsupport type");
|
||||
// break;
|
||||
// case before:
|
||||
// addStaticBeforeInterceptor(methodName, interceptorId, behavior, useContextClassLoader);
|
||||
// break;
|
||||
// case after:
|
||||
// addStaticAfterInterceptor(methodName, interceptorId, behavior, useContextClassLoader);
|
||||
// break;
|
||||
// default:
|
||||
// throw new UnsupportedOperationException("unsupport type");
|
||||
// }
|
||||
} else if(interceptor instanceof SimpleInterceptor) {
|
||||
if (interceptor instanceof SimpleAroundInterceptor) {
|
||||
addSimpleAroundInterceptor(methodName, interceptorId, behavior, useContextClassLoader);
|
||||
} else if (interceptor instanceof SimpleBeforeInterceptor) {
|
||||
addSimpleBeforeInterceptor(methodName, interceptorId, behavior, useContextClassLoader);
|
||||
} else if (interceptor instanceof SimpleAfterInterceptor) {
|
||||
addSimpleAfterInterceptor(methodName, interceptorId, behavior, useContextClassLoader);
|
||||
} else {
|
||||
throw new UnsupportedOperationException("unsupport type");
|
||||
}
|
||||
} else {
|
||||
throw new IllegalArgumentException("unsupported");
|
||||
@@ -629,7 +640,7 @@ public class JavaAssistClass implements InstrumentClass {
|
||||
after.format(" %1$s interceptor = com.nhn.pinpoint.bootstrap.interceptor.InterceptorRegistry.getInterceptor(%2$d);", StaticAroundInterceptor.class.getName(), id);
|
||||
after.format(" interceptor.after(%1$s, \"%2$s\", \"%3$s\", \"%4$s\", %5$s, %6$s, null);", target, ctClass.getName(), methodName, parameterTypeString, parameterIdentifier, returnType);
|
||||
} else {
|
||||
after.format(" %1$s interceptor = com.nhn.pinpoint.bootstrap.interceptor.InterceptorRegistry.getSimpleInterceptor(%2$d);", SimpleAroundInterceptor.class.getName(), id);
|
||||
after.format(" %1$s interceptor = (%1$s)com.nhn.pinpoint.bootstrap.interceptor.InterceptorRegistry.getSimpleInterceptor(%2$d);", SimpleAroundInterceptor.class.getName(), id);
|
||||
after.format(" interceptor.after(%1$s, %2$s, %3$s, null);", target, parameterIdentifier, returnType);
|
||||
}
|
||||
after.end();
|
||||
@@ -765,14 +776,14 @@ public class JavaAssistClass implements InstrumentClass {
|
||||
code.format(" interceptor.before(%1$s, \"%2$s\", \"%3$s\", \"%4$s\", %5$s);", target, ctClass.getName(), methodName, parameterDescription, parameterIdentifier);
|
||||
} else {
|
||||
// simpleInterceptor인덱스에서 검색하여 typecasting을 제거한다.
|
||||
code.format(" %1$s interceptor = com.nhn.pinpoint.bootstrap.interceptor.InterceptorRegistry.getSimpleInterceptor(%2$d);", SimpleAroundInterceptor.class.getName(), id);
|
||||
code.format(" %1$s interceptor = (%1$s)com.nhn.pinpoint.bootstrap.interceptor.InterceptorRegistry.getSimpleInterceptor(%2$d);", SimpleBeforeInterceptor.class.getName(), id);
|
||||
code.format(" interceptor.before(%1$s, %2$s);", target, parameterIdentifier);
|
||||
}
|
||||
code.end();
|
||||
}
|
||||
String buildBefore = code.toString();
|
||||
if (isDebug) {
|
||||
logger.debug("addStaticBeforeInterceptor catch behavior:{} code:{}", behavior.getLongName(), buildBefore);
|
||||
logger.debug("addBeforeInterceptor catch behavior:{} code:{}", behavior.getLongName(), buildBefore);
|
||||
}
|
||||
|
||||
if (behavior instanceof CtConstructor) {
|
||||
|
||||
+16
-21
@@ -2,52 +2,47 @@ package com.nhn.pinpoint.profiler.plugin;
|
||||
|
||||
import java.security.ProtectionDomain;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import com.nhn.pinpoint.bootstrap.Agent;
|
||||
import com.nhn.pinpoint.bootstrap.instrument.ByteCodeInstrumentor;
|
||||
import com.nhn.pinpoint.bootstrap.instrument.InstrumentClass;
|
||||
import com.nhn.pinpoint.bootstrap.plugin.ClassEditor;
|
||||
import com.nhn.pinpoint.bootstrap.plugin.ClassEditorFactory;
|
||||
import com.nhn.pinpoint.bootstrap.plugin.ClassEditorFactoryMapping;
|
||||
import com.nhn.pinpoint.bootstrap.plugin.DedicatedClassEditor;
|
||||
import com.nhn.pinpoint.bootstrap.plugin.PluginClassLoaderFactory;
|
||||
import com.nhn.pinpoint.bootstrap.plugin.ProfilerPluginContext;
|
||||
import com.nhn.pinpoint.exception.PinpointException;
|
||||
import com.nhn.pinpoint.profiler.modifier.AbstractModifier;
|
||||
|
||||
public class ClassEditorAdaptor extends AbstractModifier {
|
||||
private final ClassEditorFactoryMapping mapping;
|
||||
private final ProfilerPluginContext pluginContext;
|
||||
private final Logger logger = LoggerFactory.getLogger(getClass());
|
||||
private final DedicatedClassEditor editor;
|
||||
private final PluginClassLoaderFactory classLoaderFactory;
|
||||
|
||||
|
||||
public ClassEditorAdaptor(ByteCodeInstrumentor byteCodeInstrumentor, Agent agent, ClassEditorFactoryMapping mapping, ProfilerPluginContext pluginContext, PluginClassLoaderFactory classLoaderFactory) {
|
||||
public ClassEditorAdaptor(ByteCodeInstrumentor byteCodeInstrumentor, Agent agent, DedicatedClassEditor editor, PluginClassLoaderFactory classLoaderFactory) {
|
||||
super(byteCodeInstrumentor, agent);
|
||||
this.mapping = mapping;
|
||||
this.pluginContext = pluginContext;
|
||||
this.editor = editor;
|
||||
this.classLoaderFactory = classLoaderFactory;
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte[] modify(ClassLoader classLoader, String className, ProtectionDomain protectionDomain, byte[] classFileBuffer) {
|
||||
logger.debug("Editing class {}", className);
|
||||
|
||||
ClassLoader forPlugin = classLoaderFactory.get(classLoader);
|
||||
|
||||
ClassLoader old = Thread.currentThread().getContextClassLoader();
|
||||
Thread.currentThread().setContextClassLoader(forPlugin);
|
||||
|
||||
try {
|
||||
Class<?> editorFactoryClass = forPlugin.loadClass(mapping.getEditorFactoryClassName());
|
||||
|
||||
if (!ClassEditorFactory.class.isAssignableFrom(editorFactoryClass)) {
|
||||
throw new PinpointException("Illegal class editor factory mapping. factory class[" + editorFactoryClass + "] did not implent ClassEditorFactory");
|
||||
}
|
||||
|
||||
ClassEditorFactory editorFactory = (ClassEditorFactory)editorFactoryClass.newInstance();
|
||||
ClassEditor editor = editorFactory.get(pluginContext);
|
||||
|
||||
InstrumentClass target = byteCodeInstrumentor.getClass(classLoader, className, classFileBuffer);
|
||||
|
||||
return editor.edit(classLoader, target);
|
||||
} catch (PinpointException e) {
|
||||
throw e;
|
||||
} catch (Exception e) {
|
||||
throw new PinpointException("Fail to invoke plugin class editor for " + mapping.getTargetClassName() + ", editor factory: " + mapping.getEditorFactoryClassName(), e);
|
||||
String msg = "Fail to invoke plugin class editor " + editor.getClass().getName() + " for " + editor.getTargetClassName();
|
||||
logger.warn(msg, e);
|
||||
throw new PinpointException(msg, e);
|
||||
} finally {
|
||||
Thread.currentThread().setContextClassLoader(old);
|
||||
}
|
||||
@@ -56,6 +51,6 @@ public class ClassEditorAdaptor extends AbstractModifier {
|
||||
|
||||
@Override
|
||||
public String getTargetClass() {
|
||||
return mapping.getTargetClassName();
|
||||
return editor.getTargetClassName().replace('.', '/');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,100 @@
|
||||
package com.nhn.pinpoint.profiler.util;
|
||||
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import org.junit.runner.Description;
|
||||
import org.junit.runner.JUnitCore;
|
||||
import org.junit.runner.Result;
|
||||
import org.junit.runner.notification.Failure;
|
||||
import org.junit.runner.notification.RunListener;
|
||||
|
||||
public class ForkedJUnit {
|
||||
static final String JUNIT_OUTPUT_DELIMETER = "#####";
|
||||
static final String JUNIT_OUTPUT_DELIMETER_REGEXP = Pattern.quote(JUNIT_OUTPUT_DELIMETER);
|
||||
private static boolean forked = false;
|
||||
|
||||
public static boolean isForked() {
|
||||
return forked;
|
||||
}
|
||||
|
||||
|
||||
public static void main(String[] args) throws ClassNotFoundException {
|
||||
forked = true;
|
||||
|
||||
Class<?>[] classes = new Class<?>[args.length];
|
||||
|
||||
for (int i = 0; i < args.length; i++) {
|
||||
classes[i] = Class.forName(args[i]);
|
||||
}
|
||||
|
||||
JUnitCore junit = new JUnitCore();
|
||||
junit.addListener(new PrintListener());
|
||||
Result result = junit.run(classes);
|
||||
|
||||
System.exit(result.getFailureCount());
|
||||
}
|
||||
|
||||
private static class PrintListener extends RunListener {
|
||||
|
||||
@Override
|
||||
public void testRunStarted(Description description) throws Exception {
|
||||
System.out.println(JUNIT_OUTPUT_DELIMETER + "testRunStarted");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void testRunFinished(Result result) throws Exception {
|
||||
System.out.println(JUNIT_OUTPUT_DELIMETER + "testRunFinished");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void testStarted(Description description) throws Exception {
|
||||
System.out.println(JUNIT_OUTPUT_DELIMETER + "testStarted" + JUNIT_OUTPUT_DELIMETER + description.getDisplayName());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void testFinished(Description description) throws Exception {
|
||||
System.out.println(JUNIT_OUTPUT_DELIMETER + "testFinished" + JUNIT_OUTPUT_DELIMETER + description.getDisplayName());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void testFailure(Failure failure) throws Exception {
|
||||
System.out.println(JUNIT_OUTPUT_DELIMETER + "testFailure" + JUNIT_OUTPUT_DELIMETER + failureToString(failure));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void testAssumptionFailure(Failure failure) {
|
||||
System.out.println(JUNIT_OUTPUT_DELIMETER + "testAssumptionFailure" + JUNIT_OUTPUT_DELIMETER + failureToString(failure));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void testIgnored(Description description) throws Exception {
|
||||
System.out.println(JUNIT_OUTPUT_DELIMETER + "testIgnored" + JUNIT_OUTPUT_DELIMETER + description.getDisplayName());
|
||||
}
|
||||
|
||||
private String failureToString(Failure failure) {
|
||||
StringBuilder builder = new StringBuilder();
|
||||
|
||||
builder.append(failure.getTestHeader());
|
||||
builder.append(JUNIT_OUTPUT_DELIMETER);
|
||||
builder.append(failure.getException().getClass().getName());
|
||||
builder.append(JUNIT_OUTPUT_DELIMETER);
|
||||
builder.append(failure.getMessage());
|
||||
builder.append(JUNIT_OUTPUT_DELIMETER);
|
||||
|
||||
for (StackTraceElement e : failure.getException().getStackTrace()) {
|
||||
builder.append(e.getClassName());
|
||||
builder.append(',');
|
||||
builder.append(e.getMethodName());
|
||||
builder.append(',');
|
||||
builder.append(e.getFileName());
|
||||
builder.append(',');
|
||||
builder.append(e.getLineNumber());
|
||||
|
||||
builder.append(JUNIT_OUTPUT_DELIMETER);
|
||||
}
|
||||
|
||||
return builder.toString();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
package com.nhn.pinpoint.profiler.util;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target(ElementType.TYPE)
|
||||
public @interface PinpointAgent {
|
||||
String value();
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
package com.nhn.pinpoint.profiler.util;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target(ElementType.TYPE)
|
||||
public @interface PinpointConfig {
|
||||
String value();
|
||||
}
|
||||
+7
-1
@@ -8,7 +8,7 @@
|
||||
</parent>
|
||||
|
||||
<artifactId>pinpoint-test</artifactId>
|
||||
<name>pinpoint test helper libraries</name>
|
||||
<name>pinpoint test helper</name>
|
||||
<packaging>jar</packaging>
|
||||
|
||||
<dependencies>
|
||||
@@ -16,6 +16,12 @@
|
||||
<groupId>com.nhn.pinpoint</groupId>
|
||||
<artifactId>pinpoint-profiler</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>junit</groupId>
|
||||
<artifactId>junit</artifactId>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
|
||||
<!-- Logging depedencies -->
|
||||
<dependency>
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
package com.nhn.pinpoint.test.fork;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target(ElementType.TYPE)
|
||||
public @interface ExcludeLibraries {
|
||||
String[] value() default {};
|
||||
}
|
||||
@@ -1,7 +1,9 @@
|
||||
package com.nhn.pinpoint.profiler.util;
|
||||
package com.nhn.pinpoint.test.fork;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.lang.management.ManagementFactory;
|
||||
import java.net.URISyntaxException;
|
||||
import java.net.URL;
|
||||
import java.net.URLClassLoader;
|
||||
import java.util.ArrayList;
|
||||
@@ -20,19 +22,24 @@ import org.junit.runners.model.Statement;
|
||||
import com.nhn.pinpoint.common.Version;
|
||||
|
||||
public class ForkRunner extends BlockJUnit4ClassRunner {
|
||||
private static final String[] REQUIRED_CLASS_PATHS = new String[] {
|
||||
"junit",
|
||||
"pinpoint-test",
|
||||
"pinpoint/test"
|
||||
};
|
||||
|
||||
private final String agentJar;
|
||||
private final String configPath;
|
||||
private final boolean testOnChildClassLoader;
|
||||
private final String[] excludedLibraries;
|
||||
private final String[] includedLibraries;
|
||||
|
||||
public ForkRunner(Class<?> klass) throws InitializationError {
|
||||
super(klass);
|
||||
|
||||
PinpointAgent path = klass.getAnnotation(PinpointAgent.class);
|
||||
|
||||
if (path != null && path.value() != null) {
|
||||
agentJar = path.value();
|
||||
} else {
|
||||
agentJar = "target/pinpoint-agent/pinpoint-bootstrap-" + Version.VERSION + ".jar";
|
||||
}
|
||||
PinpointAgentPath path = klass.getAnnotation(PinpointAgentPath.class);
|
||||
String agentPath = (path != null && path.value() != null) ? path.value() : "target/pinpoint-agent";
|
||||
agentJar = agentPath + "/pinpoint-bootstrap-" + Version.VERSION + ".jar";
|
||||
|
||||
PinpointConfig config = klass.getAnnotation(PinpointConfig.class);
|
||||
|
||||
@@ -41,6 +48,14 @@ public class ForkRunner extends BlockJUnit4ClassRunner {
|
||||
} else {
|
||||
configPath = null;
|
||||
}
|
||||
|
||||
testOnChildClassLoader = klass.isAnnotationPresent(OnChildClassLoader.class);
|
||||
|
||||
ExcludeLibraries exclude = klass.getAnnotation(ExcludeLibraries.class);
|
||||
excludedLibraries = exclude == null ? new String[0] : exclude.value();
|
||||
|
||||
WithLibraries include = klass.getAnnotation(WithLibraries.class);
|
||||
includedLibraries = include == null ? new String[0] : include.value();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -67,6 +82,9 @@ public class ForkRunner extends BlockJUnit4ClassRunner {
|
||||
|
||||
builder.command(buildCommand());
|
||||
builder.redirectErrorStream(true);
|
||||
|
||||
System.out.println("Working directory: " + System.getProperty("user.dir"));
|
||||
System.out.println("Command: " + builder.command());
|
||||
|
||||
Process process;
|
||||
try {
|
||||
@@ -120,26 +138,44 @@ public class ForkRunner extends BlockJUnit4ClassRunner {
|
||||
}
|
||||
}
|
||||
|
||||
private String[] buildCommand() {
|
||||
private String[] buildCommand() throws URISyntaxException {
|
||||
List<String> list = new ArrayList<String>();
|
||||
|
||||
list.add(getJavaExecutable());
|
||||
list.add("-cp");
|
||||
list.add(getClassPath());
|
||||
list.add(getAgent());
|
||||
|
||||
list.add("-Dpinpoint.agentId=build.test.0");
|
||||
list.add("-Dpinpoint.applicationName=test");
|
||||
|
||||
if (isDebugMode()) {
|
||||
list.addAll(getDebugOptions());
|
||||
}
|
||||
|
||||
if (configPath != null) {
|
||||
list.add("-Dpinpoint.config=" + configPath);
|
||||
}
|
||||
|
||||
list.add(ForkedJUnit.class.getName());
|
||||
|
||||
if (testOnChildClassLoader) {
|
||||
list.add(getChildClassPath());
|
||||
}
|
||||
|
||||
list.add(getTestClass().getName());
|
||||
|
||||
return list.toArray(new String[list.size()]);
|
||||
}
|
||||
|
||||
|
||||
private boolean isDebugMode() {
|
||||
return ManagementFactory.getRuntimeMXBean().getInputArguments().toString().contains("jdwp");
|
||||
}
|
||||
|
||||
private List<String> getDebugOptions() {
|
||||
return Arrays.asList("-Xdebug", "-agentlib:jdwp=transport=dt_socket,address=1296,server=y,suspend=y");
|
||||
}
|
||||
|
||||
private String getAgent() {
|
||||
return "-javaagent:" + agentJar;
|
||||
}
|
||||
@@ -159,19 +195,63 @@ public class ForkRunner extends BlockJUnit4ClassRunner {
|
||||
|
||||
return builder.toString();
|
||||
}
|
||||
|
||||
private String getClassPath() {
|
||||
URLClassLoader cl = (URLClassLoader) ClassLoader.getSystemClassLoader();
|
||||
|
||||
private String getClassPath() throws URISyntaxException {
|
||||
StringBuilder classPath = new StringBuilder();
|
||||
|
||||
for (URL url : cl.getURLs()) {
|
||||
classPath.append(url.getPath());
|
||||
classPath.append(File.pathSeparatorChar);
|
||||
if (testOnChildClassLoader) {
|
||||
URLClassLoader cl = (URLClassLoader) ClassLoader.getSystemClassLoader();
|
||||
|
||||
outer:
|
||||
for (URL url : cl.getURLs()) {
|
||||
for (String required : REQUIRED_CLASS_PATHS) {
|
||||
if (url.getFile().contains(required)) {
|
||||
classPath.append(new File(url.toURI()).getAbsolutePath());
|
||||
classPath.append(File.pathSeparatorChar);
|
||||
continue outer;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
appendClassPath(classPath);
|
||||
}
|
||||
|
||||
return classPath.toString();
|
||||
}
|
||||
|
||||
private void appendClassPath(StringBuilder classPath) throws URISyntaxException {
|
||||
URLClassLoader cl = (URLClassLoader) ClassLoader.getSystemClassLoader();
|
||||
|
||||
outer:
|
||||
for (URL url : cl.getURLs()) {
|
||||
String urlAsString = url.toString();
|
||||
|
||||
for (String exclude : excludedLibraries) {
|
||||
if (urlAsString.contains(exclude)) {
|
||||
continue outer;
|
||||
}
|
||||
}
|
||||
|
||||
classPath.append(new File(url.toURI()).getAbsolutePath());
|
||||
classPath.append(File.pathSeparatorChar);
|
||||
}
|
||||
|
||||
for (String include : includedLibraries) {
|
||||
classPath.append(include);
|
||||
classPath.append(File.pathSeparatorChar);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private String getChildClassPath() throws URISyntaxException {
|
||||
StringBuilder classPath = new StringBuilder();
|
||||
|
||||
classPath.append(ForkedJUnit.CHILD_CLASS_PATH_PREFIX);
|
||||
appendClassPath(classPath);
|
||||
|
||||
return classPath.toString();
|
||||
}
|
||||
|
||||
private Description findDescription(Description description, String displayName) {
|
||||
if (displayName.equals(description.getDisplayName())) {
|
||||
return description;
|
||||
@@ -201,7 +281,6 @@ public class ForkRunner extends BlockJUnit4ClassRunner {
|
||||
|
||||
for (int i = 0; i < traceInText.size(); i++) {
|
||||
String trace = traceInText.get(i);
|
||||
System.out.println(trace);
|
||||
String[] tokens = trace.split(",");
|
||||
|
||||
stackTrace[i] = new StackTraceElement(tokens[0], tokens[1], tokens[2], Integer.valueOf(tokens[3]));
|
||||
|
||||
@@ -1,5 +1,12 @@
|
||||
package com.nhn.pinpoint.profiler.util;
|
||||
package com.nhn.pinpoint.test.fork;
|
||||
|
||||
import java.io.File;
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.URL;
|
||||
import java.net.URLClassLoader;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import org.junit.runner.Description;
|
||||
@@ -9,6 +16,7 @@ import org.junit.runner.notification.Failure;
|
||||
import org.junit.runner.notification.RunListener;
|
||||
|
||||
public class ForkedJUnit {
|
||||
static final String CHILD_CLASS_PATH_PREFIX = "-child=";
|
||||
static final String JUNIT_OUTPUT_DELIMETER = "#####";
|
||||
static final String JUNIT_OUTPUT_DELIMETER_REGEXP = Pattern.quote(JUNIT_OUTPUT_DELIMETER);
|
||||
private static boolean forked = false;
|
||||
@@ -18,21 +26,61 @@ public class ForkedJUnit {
|
||||
}
|
||||
|
||||
|
||||
public static void main(String[] args) throws ClassNotFoundException {
|
||||
public static void main(String[] args) throws ClassNotFoundException, MalformedURLException {
|
||||
forked = true;
|
||||
|
||||
Class<?>[] classes = new Class<?>[args.length];
|
||||
int from = 0;
|
||||
ClassLoader classLoader = ClassLoader.getSystemClassLoader();
|
||||
|
||||
for (int i = 0; i < args.length; i++) {
|
||||
classes[i] = Class.forName(args[i]);
|
||||
if (args[0].startsWith(CHILD_CLASS_PATH_PREFIX)) {
|
||||
String jars = args[0].substring(CHILD_CLASS_PATH_PREFIX.length());
|
||||
List<URL> urls = getJarUrls(jars);
|
||||
classLoader = new URLClassLoader(urls.toArray(new URL[urls.size()]), classLoader);
|
||||
from = 1;
|
||||
}
|
||||
|
||||
JUnitCore junit = new JUnitCore();
|
||||
junit.addListener(new PrintListener());
|
||||
Result result = junit.run(classes);
|
||||
List<String> testClassNames = Arrays.asList(args).subList(from, args.length);
|
||||
List<Class<?>> classes = loadTestClasses(classLoader, testClassNames);
|
||||
|
||||
Result result = runTests(classes);
|
||||
|
||||
System.exit(result.getFailureCount());
|
||||
}
|
||||
|
||||
|
||||
private static Result runTests(List<Class<?>> classes) {
|
||||
JUnitCore junit = new JUnitCore();
|
||||
junit.addListener(new PrintListener());
|
||||
Result result = junit.run(classes.toArray(new Class<?>[classes.size()]));
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
private static List<URL> getJarUrls(String jars) throws MalformedURLException {
|
||||
String[] tokens = jars.split(File.pathSeparator);
|
||||
|
||||
List<URL> urls = new ArrayList<URL>(tokens.length);
|
||||
for (String token : tokens) {
|
||||
File file = new File(token);
|
||||
urls.add(file.toURI().toURL());
|
||||
}
|
||||
return urls;
|
||||
}
|
||||
|
||||
|
||||
private static List<Class<?>> loadTestClasses(ClassLoader classLoader, List<String> testClassNames) throws ClassNotFoundException {
|
||||
List<Class<?>> classes = new ArrayList<Class<?>>(testClassNames.size());
|
||||
|
||||
ClassLoader old = Thread.currentThread().getContextClassLoader();
|
||||
Thread.currentThread().setContextClassLoader(classLoader);
|
||||
|
||||
for (String testClassName : testClassNames) {
|
||||
classes.add(classLoader.loadClass(testClassName));
|
||||
}
|
||||
|
||||
Thread.currentThread().setContextClassLoader(old);
|
||||
return classes;
|
||||
}
|
||||
|
||||
private static class PrintListener extends RunListener {
|
||||
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
package com.nhn.pinpoint.test.fork;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target(ElementType.TYPE)
|
||||
public @interface OnChildClassLoader {
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
package com.nhn.pinpoint.profiler.util;
|
||||
package com.nhn.pinpoint.test.fork;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
@@ -7,6 +7,6 @@ import java.lang.annotation.Target;
|
||||
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target(ElementType.TYPE)
|
||||
public @interface PinpointAgent {
|
||||
String value();
|
||||
public @interface PinpointAgentPath {
|
||||
String value() default "target/pinpoint-agent";
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
package com.nhn.pinpoint.profiler.util;
|
||||
package com.nhn.pinpoint.test.fork;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
package com.nhn.pinpoint.test.fork;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target(ElementType.TYPE)
|
||||
public @interface WithLibraries {
|
||||
String[] value() default {};
|
||||
}
|
||||
Reference in New Issue
Block a user