From 94e6a2f2ed4dbe93ec6cd6f873f6381a293b2966 Mon Sep 17 00:00:00 2001 From: Woonduk Kang Date: Tue, 4 Sep 2012 10:28:26 +0000 Subject: [PATCH] =?UTF-8?q?[=EA=B0=95=EC=9A=B4=EB=8D=95]=20[LUCYSUS-1744]?= =?UTF-8?q?=20tracevariable=20=EC=B6=94=EA=B0=80api=EB=A5=BC=20=EB=B3=84?= =?UTF-8?q?=EB=8F=84=20=ED=81=B4=EB=9E=98=EC=8A=A4=EB=A1=9C=20=EC=B6=94?= =?UTF-8?q?=EC=B6=9C.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.bds.nhncorp.com/pe/hippo-tomcat-profiler/trunk@577 84d0f5b1-2673-498c-a247-62c4ff18d310 --- .../interceptor/bci/InstrumentClass.java | 2 + .../interceptor/bci/JavaAssistClass.java | 30 +++++++-- .../db/mysql/MySQLStatementModifier.java | 23 +------ .../CloseConnectionInterceptor.java | 4 +- .../CreateConnectionInterceptor.java | 1 + .../CreateStatementInterceptor.java | 64 ++++++++----------- .../ExecuteQueryMethodInterceptor.java | 32 ++++++++-- 7 files changed, 83 insertions(+), 73 deletions(-) diff --git a/src/main/java/com/profiler/interceptor/bci/InstrumentClass.java b/src/main/java/com/profiler/interceptor/bci/InstrumentClass.java index 9ff9bb062..55a3b4164 100644 --- a/src/main/java/com/profiler/interceptor/bci/InstrumentClass.java +++ b/src/main/java/com/profiler/interceptor/bci/InstrumentClass.java @@ -15,4 +15,6 @@ public interface InstrumentClass { byte[] toBytecode(); Class toClass(); + + boolean addTraceVariable(String variableName, String setterName, String getterName, String variableType); } diff --git a/src/main/java/com/profiler/interceptor/bci/JavaAssistClass.java b/src/main/java/com/profiler/interceptor/bci/JavaAssistClass.java index 85582239b..b8c1d1efa 100644 --- a/src/main/java/com/profiler/interceptor/bci/JavaAssistClass.java +++ b/src/main/java/com/profiler/interceptor/bci/JavaAssistClass.java @@ -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); diff --git a/src/main/java/com/profiler/modifier/db/mysql/MySQLStatementModifier.java b/src/main/java/com/profiler/modifier/db/mysql/MySQLStatementModifier.java index f6d8abaa3..cc2c6d6e7 100644 --- a/src/main/java/com/profiler/modifier/db/mysql/MySQLStatementModifier.java +++ b/src/main/java/com/profiler/modifier/db/mysql/MySQLStatementModifier.java @@ -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. - } - } + } \ No newline at end of file diff --git a/src/main/java/com/profiler/modifier/db/mysql/interceptors/CloseConnectionInterceptor.java b/src/main/java/com/profiler/modifier/db/mysql/interceptors/CloseConnectionInterceptor.java index 591cc49ba..a053ec2db 100644 --- a/src/main/java/com/profiler/modifier/db/mysql/interceptors/CloseConnectionInterceptor.java +++ b/src/main/java/com/profiler/modifier/db/mysql/interceptors/CloseConnectionInterceptor.java @@ -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); diff --git a/src/main/java/com/profiler/modifier/db/mysql/interceptors/CreateConnectionInterceptor.java b/src/main/java/com/profiler/modifier/db/mysql/interceptors/CreateConnectionInterceptor.java index abccde59a..1961a8fef 100644 --- a/src/main/java/com/profiler/modifier/db/mysql/interceptors/CreateConnectionInterceptor.java +++ b/src/main/java/com/profiler/modifier/db/mysql/interceptors/CreateConnectionInterceptor.java @@ -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; } diff --git a/src/main/java/com/profiler/modifier/db/mysql/interceptors/CreateStatementInterceptor.java b/src/main/java/com/profiler/modifier/db/mysql/interceptors/CreateStatementInterceptor.java index cef5e5e1b..ef4a458a6 100644 --- a/src/main/java/com/profiler/modifier/db/mysql/interceptors/CreateStatementInterceptor.java +++ b/src/main/java/com/profiler/modifier/db/mysql/interceptors/CreateStatementInterceptor.java @@ -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; } + } diff --git a/src/main/java/com/profiler/modifier/db/mysql/interceptors/ExecuteQueryMethodInterceptor.java b/src/main/java/com/profiler/modifier/db/mysql/interceptors/ExecuteQueryMethodInterceptor.java index a2edc8e32..b94d3065f 100644 --- a/src/main/java/com/profiler/modifier/db/mysql/interceptors/ExecuteQueryMethodInterceptor.java +++ b/src/main/java/com/profiler/modifier/db/mysql/interceptors/ExecuteQueryMethodInterceptor.java @@ -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);