[강운덕] [LUCYSUS-1744] tracevariable 추가api를 별도 클래스로 추출.

git-svn-id: http://svn.bds.nhncorp.com/pe/hippo-tomcat-profiler/trunk@577 84d0f5b1-2673-498c-a247-62c4ff18d310
This commit is contained in:
Woonduk Kang
2012-09-04 10:28:26 +00:00
parent ee0b2d1e36
commit 94e6a2f2ed
7 changed files with 83 additions and 73 deletions
@@ -15,4 +15,6 @@ public interface InstrumentClass {
byte[] toBytecode();
Class<?> toClass();
boolean addTraceVariable(String variableName, String setterName, String getterName, String variableType);
}
@@ -4,12 +4,7 @@ import java.io.IOException;
import java.util.logging.Level;
import java.util.logging.Logger;
import javassist.CannotCompileException;
import javassist.CtBehavior;
import javassist.CtClass;
import javassist.CtConstructor;
import javassist.CtMethod;
import javassist.NotFoundException;
import javassist.*;
import com.profiler.interceptor.Interceptor;
import com.profiler.interceptor.InterceptorRegistry;
@@ -34,6 +29,29 @@ public class JavaAssistClass implements InstrumentClass {
return ctClass;
}
// TODO return type을 별도 exception으로 할지 추가 검토가 필요함.
public boolean addTraceVariable(String variableName, String setterName, String getterName, String variableType) {
try {
CtClass type = instrumentor.getClassPool().get(variableType);
CtField traceVariable = new CtField(type, variableName, ctClass);
ctClass.addField(traceVariable);
CtMethod setterMethod = CtNewMethod.setter(setterName, traceVariable);
ctClass.addMethod(setterMethod);
CtMethod getterMethod = CtNewMethod.getter(getterName, traceVariable);
ctClass.addMethod(getterMethod);
return true;
} catch (NotFoundException e) {
if (logger.isLoggable(Level.WARNING)) {
logger.log(Level.WARNING, e.getMessage(), e);
}
} catch (CannotCompileException e) {
if (logger.isLoggable(Level.WARNING)) {
logger.log(Level.WARNING, e.getMessage(), e);
}
}
return false;
}
@Override
public boolean addInterceptor(String methodName, String[] args, Interceptor interceptor) {
return addInterceptor(methodName, args, interceptor, Type.auto);
@@ -45,7 +45,8 @@ public class MySQLStatementModifier extends AbstractModifier {
if (logger.isLoggable(Level.INFO)) {
logger.info("executeUpdate =" + executeUpdate);
}
addTraceData((JavaAssistClass) aClass);
// TODO 아무래도 에러 체크를 Exception으로 변경하는게 좋을것 같음.
aClass.addTraceVariable("__url", "__setUrl", "__getUrl", "java.lang.String");
if (executeQuery && executeQuery) {
@@ -54,23 +55,5 @@ public class MySQLStatementModifier extends AbstractModifier {
return null;
}
private void addTraceData(JavaAssistClass aClass) {
try {
ClassPool classPool1 = byteCodeInstrumentor.getClassPool();
JavaAssistClass jc = (JavaAssistClass) aClass;
CtClass ctClass = jc.getCtClass();
CtClass string = classPool1.get("java.lang.String");
CtField traceUrl = new CtField(string, "__url", ctClass);
traceUrl.setModifiers(AccessFlag.PUBLIC);
ctClass.addField(traceUrl);
CtMethod setUrl = CtNewMethod.setter("__setUrl", traceUrl);
ctClass.addMethod(setUrl);
CtMethod getUrl = CtNewMethod.getter("__getUrl", traceUrl);
ctClass.addMethod(getUrl);
} catch (NotFoundException e) {
e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates.
} catch (CannotCompileException e) {
e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates.
}
}
}
@@ -1,10 +1,7 @@
package com.profiler.modifier.db.mysql.interceptors;
import com.profiler.interceptor.StaticAfterInterceptor;
import com.profiler.interceptor.StaticAroundInterceptor;
import com.profiler.interceptor.StaticBeforeInterceptor;
import com.profiler.modifier.db.ConnectionTrace;
import com.profiler.util.InterceptorUtils;
import java.sql.Connection;
import java.util.Arrays;
@@ -20,6 +17,7 @@ public class CloseConnectionInterceptor implements StaticBeforeInterceptor {
if (logger.isLoggable(Level.INFO)) {
logger.info("before className:" + className + " methodName:" + methodName + " args:" + Arrays.toString(args));
}
if (target instanceof Connection) {
ConnectionTrace connectionTrace = ConnectionTrace.getConnectionTrace();
connectionTrace.closeConnection((Connection) target);
@@ -18,6 +18,7 @@ public class CreateConnectionInterceptor implements StaticAfterInterceptor {
if (logger.isLoggable(Level.INFO)) {
logger.info("after className:" + className + " methodName:" + methodName + " args:" + Arrays.toString(args) + " result:" + result);
}
if (InterceptorUtils.isThrowable(result)) {
return;
}
@@ -21,7 +21,7 @@ public class CreateStatementInterceptor implements StaticAfterInterceptor {
private final Logger logger = Logger.getLogger(CreateStatementInterceptor.class.getName());
private Field urlField;
private Method setUrl = null;
@Override
public void after(Object target, String className, String methodName, Object[] args, Object result) {
@@ -31,48 +31,34 @@ public class CreateStatementInterceptor implements StaticAfterInterceptor {
if (Trace.getCurrentTraceId() == null) {
return;
}
if (target instanceof Connection) {
ConnectionTrace connectionTrace = ConnectionTrace.getConnectionTrace();
String connectionUrl = connectionTrace.getConnectionUrl((Connection) target);
try {
Method setUrl = result.getClass().getMethod("__setUrl", String.class);
setUrl.invoke(result, connectionUrl);
} catch (NoSuchMethodException e) {
e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates.
} catch (InvocationTargetException e) {
e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates.
} catch (IllegalAccessException e) {
e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates.
}
// Method[] declaredMethods = result.getClass().getDeclaredMethods();
// for(Method m : declaredMethods) {
// System.out.println(m);
// }
// Field urlField = getURLField(result);
// urlField.setAccessible(true);
// urlField.set(result, connectionUrl);
}
}
private Field getURLField(Object result) {
Field urlField = this.urlField;
if(urlField == null) {
urlField = ReflectionUtils.findField(result.getClass(), "__url");
this.urlField = urlField;
if (target instanceof Connection) {
ConnectionTrace connectionTrace = ConnectionTrace.getConnectionTrace();
String connectionUrl = connectionTrace.getConnectionUrl((Connection) target);
setUrl(result, connectionUrl);
}
return urlField;
}
private Field findField(Object result, String fieldName) {
Field[] declaredFields = result.getClass().getDeclaredFields();
for(Field f: declaredFields) {
if(f.getName().equals(fieldName)) {
return f;
private void setUrl(Object result, String connectionUrl) {
try {
if (setUrl == null) {
setUrl = result.getClass().getMethod("__setUrl", String.class);
}
setUrl.invoke(result, connectionUrl);
} catch (NoSuchMethodException e) {
if (logger.isLoggable(Level.WARNING)) {
logger.log(Level.WARNING, e.getMessage(), e);
}
} catch (InvocationTargetException e) {
if (logger.isLoggable(Level.WARNING)) {
logger.log(Level.WARNING, e.getMessage(), e);
}
} catch (IllegalAccessException e) {
if (logger.isLoggable(Level.WARNING)) {
logger.log(Level.WARNING, e.getMessage(), e);
}
}
return null;
}
}
@@ -7,6 +7,7 @@ import com.profiler.interceptor.StaticAroundInterceptor;
import com.profiler.util.ReflectionUtils;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.net.URL;
import java.util.Arrays;
@@ -22,6 +23,8 @@ public class ExecuteQueryMethodInterceptor implements StaticAroundInterceptor {
private final Logger logger = Logger.getLogger(ExecuteQueryMethodInterceptor.class.getName());
private Method getUrl = null;
@Override
public void before(Object target, String className, String methodName, Object[] args) {
if (logger.isLoggable(Level.INFO)) {
@@ -35,10 +38,7 @@ public class ExecuteQueryMethodInterceptor implements StaticAroundInterceptor {
/**
* If method was not called by request handler, we skip tagging.
*/
Method getUrl = target.getClass().getMethod("__getUrl");
String url = (String) getUrl.invoke(target);
System.out.println("url:" + url);
String url = getUrl(target);
Trace.recordRpcName("mysql", url);
//
@@ -57,7 +57,29 @@ public class ExecuteQueryMethodInterceptor implements StaticAroundInterceptor {
}
}
@Override
private String getUrl(Object target) {
try {
if(getUrl == null) {
getUrl = target.getClass().getMethod("__getUrl");
}
return (String) getUrl.invoke(target);
} catch (NoSuchMethodException e) {
if (logger.isLoggable(Level.WARNING)) {
logger.log(Level.WARNING, e.getMessage(), e);
}
} catch (IllegalAccessException e) {
if (logger.isLoggable(Level.WARNING)) {
logger.log(Level.WARNING, e.getMessage(), e);
}
} catch (InvocationTargetException e) {
if (logger.isLoggable(Level.WARNING)) {
logger.log(Level.WARNING, e.getMessage(), e);
}
}
return null;
}
@Override
public void after(Object target, String className, String methodName, Object[] args, Object result) {
if (logger.isLoggable(Level.INFO)) {
logger.info("after className:" + className + " methodName:" + methodName + " args:" + Arrays.toString(args) + " result:" + result);