Merge branch '1.0.3'

Conflicts:
	bootstrap/src/main/java/com/nhn/pinpoint/bootstrap/instrument/InstrumentClass.java
	profiler/src/main/java/com/nhn/pinpoint/profiler/interceptor/bci/JavaAssistClass.java
	profiler/src/main/java/com/nhn/pinpoint/profiler/modifier/redis/JedisModifier.java
	profiler/src/main/java/com/nhn/pinpoint/profiler/modifier/redis/JedisPipelineModifier.java
	profiler/src/main/java/com/nhn/pinpoint/profiler/modifier/redis/RedisClusterModifier.java
	profiler/src/main/java/com/nhn/pinpoint/profiler/modifier/redis/RedisClusterPipelineModifier.java
This commit is contained in:
Jaehong Kim
2014-11-03 10:46:30 +09:00
15 changed files with 312 additions and 19 deletions
@@ -0,0 +1,41 @@
package com.nhn.pinpoint.profiler.interceptor.bci;
import java.util.List;
/**
* @author emeroad
*/
public class DeclaredMethodsForce {
private final List<Method> declaredMethods;
private final List<FailMethod> failDeclaredMethods;
public DeclaredMethodsForce(List<Method> successMethod, List<FailMethod> failDeclaredMethods) {
this.declaredMethods = successMethod;
this.failDeclaredMethods = failDeclaredMethods;
}
public List<Method> getDeclaredMethods() {
return declaredMethods;
}
public List<FailMethod> getFailDeclaredMethods() {
return failDeclaredMethods;
}
public static class FailMethod extends Method {
private final Throwable caused;
public FailMethod(String methodName, String[] methodParams, Throwable caused) {
super(methodName, methodParams);
this.caused = caused;
}
public Throwable getCaused() {
return caused;
}
}
}
@@ -60,13 +60,19 @@ import com.nhn.pinpoint.profiler.modifier.orm.ibatis.SqlMapClientImplModifier;
import com.nhn.pinpoint.profiler.modifier.orm.ibatis.SqlMapSessionImplModifier;
import com.nhn.pinpoint.profiler.modifier.orm.mybatis.DefaultSqlSessionModifier;
import com.nhn.pinpoint.profiler.modifier.orm.mybatis.SqlSessionTemplateModifier;
import com.nhn.pinpoint.profiler.modifier.redis.BinaryJedisModifier;
import com.nhn.pinpoint.profiler.modifier.redis.BinaryRedisClusterModifier;
import com.nhn.pinpoint.profiler.modifier.redis.BinaryTriplesRedisClusterModifier;
import com.nhn.pinpoint.profiler.modifier.redis.GatewayModifier;
import com.nhn.pinpoint.profiler.modifier.redis.GatewayServerModifier;
import com.nhn.pinpoint.profiler.modifier.redis.JedisClientModifier;
import com.nhn.pinpoint.profiler.modifier.redis.JedisModifier;
import com.nhn.pinpoint.profiler.modifier.redis.JedisMultiKeyPipelineBaseModifier;
import com.nhn.pinpoint.profiler.modifier.redis.JedisPipelineBaseModifier;
import com.nhn.pinpoint.profiler.modifier.redis.JedisPipelineModifier;
import com.nhn.pinpoint.profiler.modifier.redis.RedisClusterModifier;
import com.nhn.pinpoint.profiler.modifier.redis.RedisClusterPipelineModifier;
import com.nhn.pinpoint.profiler.modifier.redis.TriplesRedisClusterModifier;
import com.nhn.pinpoint.profiler.modifier.servlet.HttpServletModifier;
import com.nhn.pinpoint.profiler.modifier.servlet.SpringFrameworkServletModifier;
import com.nhn.pinpoint.profiler.modifier.spring.beans.AbstractAutowireCapableBeanFactoryModifier;
@@ -384,11 +390,14 @@ public class DefaultModifierRegistry implements ModifierRegistry {
public void addRedisSupport() {
if(profilerConfig.isRedisEnabled()) {
addModifier(new BinaryJedisModifier(byteCodeInstrumentor, agent));
addModifier(new JedisModifier(byteCodeInstrumentor, agent));
}
if(profilerConfig.isRedisPipelineEnabled()) {
addModifier(new JedisClientModifier(byteCodeInstrumentor, agent));
addModifier(new JedisPipelineBaseModifier(byteCodeInstrumentor, agent));
addModifier(new JedisMultiKeyPipelineBaseModifier(byteCodeInstrumentor, agent));
addModifier(new JedisPipelineModifier(byteCodeInstrumentor, agent));
}
}
@@ -400,6 +409,9 @@ public class DefaultModifierRegistry implements ModifierRegistry {
if(profilerConfig.isNbaseArcEnabled()) {
addModifier(new RedisClusterModifier(byteCodeInstrumentor, agent));
addModifier(new BinaryRedisClusterModifier(byteCodeInstrumentor, agent));
addModifier(new TriplesRedisClusterModifier(byteCodeInstrumentor, agent));
addModifier(new BinaryTriplesRedisClusterModifier(byteCodeInstrumentor, agent));
}
if(profilerConfig.isNbaseArcPipelineEnabled()) {
@@ -61,7 +61,7 @@ public class GatewayModifier extends AbstractModifier {
return instrumentClass.toBytecode();
} catch (Exception e) {
if (logger.isWarnEnabled()) {
logger.warn("redis.GatewayModifier(nBase-ARC) fail. Target class is " + getTargetClass() + ", Caused " + e.getMessage(), e);
logger.warn("Failed to modifier. caused={}", e.getMessage(), e);
}
}
@@ -59,7 +59,7 @@ public class GatewayServerModifier extends AbstractModifier {
return instrumentClass.toBytecode();
} catch (Exception e) {
if (logger.isWarnEnabled()) {
logger.warn("redis.GatewayServerModifier(nBase-ARC) fail. Target class is " + getTargetClass() + ", Caused " + e.getMessage(), e);
logger.warn("Failed to modifier. caused={}", e.getMessage(), e);
}
}
@@ -52,7 +52,7 @@ public class JedisClientModifier extends AbstractModifier {
return instrumentClass.toBytecode();
} catch (Exception e) {
if (logger.isWarnEnabled()) {
logger.warn("redis.JedisClientModifier(Jedis) fail. Target class is " + getTargetClass() + ". Caused " + e.getMessage(), e);
logger.warn("Failed to modifier. caused={}", e.getMessage(), e);
}
}
@@ -13,16 +13,18 @@ import com.nhn.pinpoint.bootstrap.instrument.MethodFilter;
*
*/
public class NameBasedMethodFilter implements MethodFilter {
private static final int SYNTHETIC = 0x00001000;
private final Set<String> methodNames;
public NameBasedMethodFilter(Set<String> methodNames) {
public NameBasedMethodFilter(final Set<String> methodNames) {
this.methodNames = methodNames;
}
@Override
public boolean filter(MethodInfo ctMethod) {
final int modifiers = ctMethod.getModifiers();
if (!Modifier.isPublic(modifiers) || Modifier.isStatic(modifiers) || Modifier.isAbstract(modifiers) || Modifier.isNative(modifiers)) {
if (isSynthetic(modifiers) || !Modifier.isPublic(modifiers) || Modifier.isStatic(modifiers) || Modifier.isAbstract(modifiers) || Modifier.isNative(modifiers)) {
return true;
}
@@ -32,4 +34,8 @@ public class NameBasedMethodFilter implements MethodFilter {
return true;
}
private boolean isSynthetic(int mod) {
return (mod & SYNTHETIC) != 0;
}
}
@@ -11,8 +11,7 @@ import com.nhn.pinpoint.bootstrap.logging.PLoggerFactory;
import com.nhncorp.redis.cluster.gateway.GatewayConfig;
/**
* Gateway(nBase-ARC client) constructor interceptor
* - trace destinationId
* Gateway(nBase-ARC client) constructor interceptor - trace destinationId
*
* @author jaehong.kim
*
@@ -43,8 +42,11 @@ public class GatewayConstructorInterceptor implements SimpleAroundInterceptor, T
// over 1.1.x
traceValue.put("destinationId", config.getClusterName());
}
} catch (Exception ignored) {
} catch (Exception e) {
// backward compatibility error or expect 'class not found exception - GatewayConfig'
if (logger.isWarnEnabled()) {
logger.warn("Failed to trace destinationId('not found getClusterName' is compatibility error). caused={}", e.getMessage(), e);
}
}
((MapTraceValue) target).__setTraceBindValue(traceValue);
@@ -58,8 +58,11 @@ public class JedisConstructorInterceptor implements SimpleAroundInterceptor, Tar
endPoint.append(":");
endPoint.append(info.getPort());
}
} catch (Exception ignored) {
} catch (Exception e) {
// expect 'class not found exception - JedisShardInfo'
if (logger.isWarnEnabled()) {
logger.warn("Failed to trace endPoint('not found JedisShardInfo' is compatibility error). caused={}", e.getMessage(), e);
}
}
final Map<String, Object> traceValue = new HashMap<String, Object>();
@@ -11,8 +11,7 @@ import com.nhn.pinpoint.bootstrap.logging.PLoggerFactory;
import com.nhncorp.redis.cluster.gateway.GatewayServer;
/**
* RedisCluster pipeline(nBase-ARC client) constructor interceptor
* - trace destinationId & endPoint
* RedisCluster pipeline(nBase-ARC client) constructor interceptor - trace destinationId & endPoint
*
* @author jaehong.kim
*
@@ -39,8 +38,11 @@ public class RedisClusterPipelineConstructorInterceptor implements SimpleAroundI
try {
final GatewayServer server = (GatewayServer) args[0];
traceValue.put("endPoint", server.getAddress().getHost() + ":" + server.getAddress().getPort());
} catch(Exception ignored) {
} catch (Exception e) {
// expect 'class not found exception - GatewayServer'
if (logger.isWarnEnabled()) {
logger.warn("Failed to trace endPoint('not found GatewayServer' is compatibility error). caused={}", e.getMessage(), e);
}
}
if (args[0] instanceof MapTraceValue) {
@@ -41,8 +41,137 @@ public final class JavaAssistUtils {
return sb.toString();
}
public static String[] parseParameterDescriptor(String descriptor) {
if (descriptor == null) {
throw new NullPointerException("descriptor must not be null");
}
final String[] parameterDesc = splitParameterDesc(descriptor);
final String[] objectType = new String[parameterDesc.length];
for (int i = 0; i < parameterDesc.length; i++) {
String description = parameterDesc[i];
objectType[i] = byteCodeDescToObjectType(description);
}
return objectType;
}
public static String[] getParameterType(Class[] paramsClass) {
private static String byteCodeDescToObjectType(String description) {
final char scheme = description.charAt(0);
switch (scheme) {
case 'B':
return "byte";
case 'C':
return "char";
case 'D':
return "double";
case 'F':
return "float";
case 'I':
return "int";
case 'J':
return "long";
case 'S':
return "short";
case 'V':
return "void";
case 'Z':
return "boolean";
case 'L':
return toObjectType(description, 1);
case '[': {
return toArrayType(description);
}
}
throw new IllegalArgumentException("invalid description :" + description);
}
private static String toArrayType(String description) {
final int arraySize = getArraySize(description);
final char scheme = description.charAt(arraySize);
switch (scheme) {
case 'B':
return arrayType("byte", arraySize);
case 'C':
return arrayType("char", arraySize);
case 'D':
return arrayType("double", arraySize);
case 'F':
return arrayType("float", arraySize);
case 'I':
return arrayType("int", arraySize);
case 'J':
return arrayType("long", arraySize);
case 'S':
return arrayType("short", arraySize);
case 'V':
return arrayType("void", arraySize);
case 'Z':
return arrayType("boolean", arraySize);
case 'L':
final String objectType = toObjectType(description, arraySize + 1);
return arrayType(objectType, arraySize);
case '[': {
throw new IllegalArgumentException("invalid description" + description);
}
}
throw new IllegalArgumentException("invalid description :" + description);
}
private static String arrayType(String objectType, int arraySize) {
final String array = "[]";
final int arrayStringLength = array.length() * arraySize;
StringBuilder sb = new StringBuilder(objectType.length() + arrayStringLength);
sb.append(objectType);
for (int i = 0; i < arraySize; i++) {
sb.append(array);
}
return sb.toString();
}
private static int getArraySize(String description) {
int arraySize = 0;
for (int i = 0; i < description.length(); i++) {
final char c = description.charAt(i);
if (c == '[') {
arraySize++;
} else {
break;
}
}
return arraySize;
}
private static String toObjectType(String description, int startIndex) {
final String assistClass = description.substring(startIndex, description.length());
final String objectName = assistClass.replace('/', '.');
if (objectName.isEmpty()) {
throw new IllegalArgumentException("invalid description. objectName not found :" + description);
}
return objectName;
}
private static String[] splitParameterDesc(String descriptor) {
final String parameterDesc = getParameterDesc(descriptor);
if (parameterDesc.isEmpty()) {
return EMPTY_STRING_ARRAY;
}
return parameterDesc.split(";");
}
private static String getParameterDesc(String descriptor) {
final int start = descriptor.indexOf('(');
if (start == -1) {
throw new IllegalArgumentException("'(' not found. descriptor:" + descriptor);
}
final int end = descriptor.indexOf(')', start + 1);
if (end == -1) {
throw new IllegalArgumentException("')' not found. descriptor:" + descriptor);
}
return descriptor.substring(start + 1, end);
}
public static String[] getParameterType(Class[] paramsClass) {
if (paramsClass == null) {
return null;
}
@@ -50,6 +50,22 @@ public class JedisModifierTest extends BasePinpointTest {
assertNull(event.getExceptionMessage());
}
@Test
public void traceBinaryMethod() {
// get 명령을 실행하고 event 결과를 확인한다.
jedis.get("foo".getBytes());
final List<SpanEventBo> spanEvents = getCurrentSpanEvents();
assertEquals(1, spanEvents.size());
SpanEventBo event = spanEvents.get(0);
assertEquals(HOST + ":" + PORT, event.getEndPoint());
assertEquals("REDIS", event.getDestinationId());
assertEquals(ServiceType.REDIS, event.getServiceType());
assertNull(event.getExceptionMessage());
}
@Test
public void traceMethodThrowException() {
// 에러가 발생한 경우에 대한 event 결과를 확인한다.
@@ -66,4 +82,4 @@ public class JedisModifierTest extends BasePinpointTest {
assertNotNull(event.getExceptionMessage());
}
}
}
@@ -37,7 +37,25 @@ public class JedisPipelineModifierTest extends BasePinpointTest {
}
@Test
public void traceMethod() {
public void traceMultikeyMethod() {
// get 명령을 실행하고 event 결과를 확인한다.
Pipeline pipeline = jedis.pipelined();
pipeline.mget("foo");
pipeline.syncAndReturnAll();
final List<SpanEventBo> spanEvents = getCurrentSpanEvents();
assertEquals(2, spanEvents.size());
SpanEventBo event = spanEvents.get(0);
System.out.println(event);
assertEquals(HOST + ":" + PORT, event.getEndPoint());
assertEquals("REDIS", event.getDestinationId());
assertEquals(ServiceType.REDIS, event.getServiceType());
assertNull(event.getExceptionMessage());
}
@Test
public void traceBaseMethod() {
// get 명령을 실행하고 event 결과를 확인한다.
Pipeline pipeline = jedis.pipelined();
pipeline.get("foo");
@@ -46,13 +64,14 @@ public class JedisPipelineModifierTest extends BasePinpointTest {
final List<SpanEventBo> spanEvents = getCurrentSpanEvents();
assertEquals(2, spanEvents.size());
SpanEventBo event = spanEvents.get(0);
System.out.println(event);
assertEquals(HOST + ":" + PORT, event.getEndPoint());
assertEquals("REDIS", event.getDestinationId());
assertEquals(ServiceType.REDIS, event.getServiceType());
assertNull(event.getExceptionMessage());
}
@Test
public void traceMethodThrowException() {
// 에러가 발생한 경우에 대한 event 결과를 확인한다.
@@ -29,7 +29,6 @@ public class RedisClusterModifierTest extends BasePinpointTest {
@Before
public void before() {
redis = new RedisCluster(HOST, PORT);
}
@Test
@@ -45,6 +44,20 @@ public class RedisClusterModifierTest extends BasePinpointTest {
assertEquals(ServiceType.NBASE_ARC, event.getServiceType());
assertNull(event.getExceptionMessage());
}
@Test
public void traceBinaryMethod() {
redis.get("foo".getBytes());
final List<SpanEventBo> spanEvents = getCurrentSpanEvents();
assertEquals(1, spanEvents.size());
SpanEventBo event = spanEvents.get(0);
assertEquals("NBASE_ARC", event.getDestinationId());
assertEquals(HOST + ":" + PORT, event.getEndPoint());
assertEquals(ServiceType.NBASE_ARC, event.getServiceType());
assertNull(event.getExceptionMessage());
}
@Test
public void traceDestinationId() {
@@ -51,6 +51,25 @@ public class RedisClusterPipelineModifierTest extends BasePinpointTest {
assertNull(event.getExceptionMessage());
}
@Test
public void traceBinaryMethod() {
pipeline.get("foo".getBytes());
pipeline.syncAndReturnAll();
final List<SpanEventBo> spanEvents = getCurrentSpanEvents();
for (SpanEventBo bo : spanEvents) {
System.out.println("### " + bo);
}
assertEquals(2, spanEvents.size());
SpanEventBo event = spanEvents.get(0);
assertEquals("NBASE_ARC", event.getDestinationId());
assertEquals(HOST + ":" + PORT, event.getEndPoint());
assertEquals(ServiceType.NBASE_ARC, event.getServiceType());
assertNull(event.getExceptionMessage());
}
@Test
public void traceDestinationId() {
GatewayConfig config = new GatewayConfig();
@@ -33,8 +33,39 @@ public class JavaAssistUtilsTest {
String clsDescription = JavaAssistUtils.getParameterDescription(new Class[]{int.class});
logger.info(clsDescription);
Assert.assertEquals(ctDescription, clsDescription);
}
@Test
public void testParseParameterDescriptor() throws Exception {
Assert.assertArrayEquals(JavaAssistUtils.parseParameterDescriptor("()V"), new String[]{});
Assert.assertArrayEquals(JavaAssistUtils.parseParameterDescriptor("(I)I"), new String[]{"int"});
Assert.assertArrayEquals(JavaAssistUtils.parseParameterDescriptor("(I;D)I"), new String[]{"int", "double"});
Assert.assertArrayEquals(JavaAssistUtils.parseParameterDescriptor("(B;F;S)I"), new String[]{"byte", "float", "short"});
Assert.assertArrayEquals(JavaAssistUtils.parseParameterDescriptor("(Ljava/lang/String)I"), new String[]{"java.lang.String"});
Assert.assertArrayEquals(JavaAssistUtils.parseParameterDescriptor("(Ljava/lang/String;J)I"), new String[]{"java.lang.String", "long"});
Assert.assertArrayEquals(JavaAssistUtils.parseParameterDescriptor("(J;Ljava/lang/Object;Z)I"), new String[]{"long", "java.lang.Object", "boolean"});
}
@Test
public void testParseParameterDescriptor_array() throws Exception {
Assert.assertArrayEquals(JavaAssistUtils.parseParameterDescriptor("([I)I"), new String[]{"int[]"});
Assert.assertArrayEquals(JavaAssistUtils.parseParameterDescriptor("([I;J)I"), new String[]{"int[]", "long"});
Assert.assertArrayEquals(JavaAssistUtils.parseParameterDescriptor("([J;[I)I"), new String[]{"long[]", "int[]"});
Assert.assertArrayEquals(JavaAssistUtils.parseParameterDescriptor("([Ljava/lang/String)"), new String[]{"java.lang.String[]"});
Assert.assertArrayEquals(JavaAssistUtils.parseParameterDescriptor("(Ljava/lang/String;[[J)"), new String[]{"java.lang.String", "long[][]"});
Assert.assertArrayEquals(JavaAssistUtils.parseParameterDescriptor("(Ljava/lang/Object;[[Ljava/lang/String)"), new String[]{"java.lang.Object", "java.lang.String[][]"});
Assert.assertArrayEquals(JavaAssistUtils.parseParameterDescriptor("([[[Ljava/lang/String)"), new String[]{"java.lang.String[][][]"});
Assert.assertArrayEquals(JavaAssistUtils.parseParameterDescriptor("([[[I)"), new String[]{"int[][][]"});
}
@Test