From 01bf8eb1080c14330d352f52748caea17a2d3868 Mon Sep 17 00:00:00 2001 From: Chisu Yu Date: Thu, 30 Aug 2012 08:47:51 +0000 Subject: [PATCH] =?UTF-8?q?[=EC=9C=A0=EC=B9=98=EC=88=98]=20[NOBTS]=20modif?= =?UTF-8?q?ied?= 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@564 84d0f5b1-2673-498c-a247-62c4ff18d310 --- src/main/java/com/profiler/context/Trace.java | 14 +++++ .../interceptor/bci/JavaAssistClass.java | 3 + .../modifier/arcus/ArcusClientModifier.java | 49 ++++++++++++++++ .../ExecuteMethodInterceptor.java | 22 +++++++ .../mysql/MySQLPreparedStatementModifier.java | 2 +- .../db/mysql/MySQLStatementModifier.java | 57 ++++--------------- .../ExecuteQueryMethodInterceptor.java | 16 ++++++ .../ExecuteUpdateMethodInterceptor.java | 55 ++++++++++++++++++ 8 files changed, 170 insertions(+), 48 deletions(-) create mode 100644 src/main/java/com/profiler/modifier/arcus/ArcusClientModifier.java create mode 100644 src/main/java/com/profiler/modifier/arcus/interceptors/ExecuteMethodInterceptor.java create mode 100644 src/main/java/com/profiler/modifier/db/mysql/interceptors/ExecuteUpdateMethodInterceptor.java diff --git a/src/main/java/com/profiler/context/Trace.java b/src/main/java/com/profiler/context/Trace.java index 19714222d..4933f1698 100644 --- a/src/main/java/com/profiler/context/Trace.java +++ b/src/main/java/com/profiler/context/Trace.java @@ -26,6 +26,11 @@ public class Trace { } + /** + * Get current TraceID or if's not exists create new one and return it. + * + * @return + */ public static TraceID getTraceId() { TraceID id = traceId.get(); @@ -38,6 +43,15 @@ public class Trace { return id; } + /** + * Get current TraceID. If it was not set this will return null. + * + * @return + */ + public static TraceID getCurrentTraceId() { + return traceId.get(); + } + public static List getTracers() { return tracers; } diff --git a/src/main/java/com/profiler/interceptor/bci/JavaAssistClass.java b/src/main/java/com/profiler/interceptor/bci/JavaAssistClass.java index 7ec8203df..7ee813503 100644 --- a/src/main/java/com/profiler/interceptor/bci/JavaAssistClass.java +++ b/src/main/java/com/profiler/interceptor/bci/JavaAssistClass.java @@ -32,6 +32,9 @@ public class JavaAssistClass implements InstrumentClass { @Override public boolean addInterceptor(String methodName, String[] args, Interceptor interceptor) { + if (interceptor == null) + return false; + int id = InterceptorRegistry.addInterceptor(interceptor); try { CtMethod method = getMethod(methodName, args); diff --git a/src/main/java/com/profiler/modifier/arcus/ArcusClientModifier.java b/src/main/java/com/profiler/modifier/arcus/ArcusClientModifier.java new file mode 100644 index 000000000..ac0f75000 --- /dev/null +++ b/src/main/java/com/profiler/modifier/arcus/ArcusClientModifier.java @@ -0,0 +1,49 @@ +package com.profiler.modifier.arcus; + +import java.security.ProtectionDomain; +import java.util.logging.Level; +import java.util.logging.Logger; + +import javassist.ByteArrayClassPath; + +import com.profiler.interceptor.Interceptor; +import com.profiler.interceptor.bci.ByteCodeInstrumentor; +import com.profiler.interceptor.bci.InstrumentClass; +import com.profiler.modifier.AbstractModifier; + +/** + * + * @author netspider + * + */ +public class ArcusClientModifier extends AbstractModifier { + + private final Logger logger = Logger.getLogger(ArcusClientModifier.class.getName()); + + public ArcusClientModifier(ByteCodeInstrumentor byteCodeInstrumentor) { + super(byteCodeInstrumentor); + } + + public String getTargetClass() { + return "org/apache/http/impl/client/AbstractHttpClient"; + } + + public byte[] modify(ClassLoader classLoader, String javassistClassName, ProtectionDomain protectedDomain, byte[] classFileBuffer) { + if (logger.isLoggable(Level.INFO)) { + logger.info("Modifing. " + javassistClassName); + } + + Interceptor interceptor = newInterceptor(classLoader, protectedDomain, "com.profiler.modifier.connector.interceptors.ExecuteMethodInterceptor"); + if (interceptor == null) { + return null; + } + + byteCodeInstrumentor.checkLibrary(classLoader, javassistClassName); + classPool.insertClassPath(new ByteArrayClassPath(javassistClassName, classFileBuffer)); + + InstrumentClass aClass = byteCodeInstrumentor.getClass(javassistClassName); + aClass.addInterceptor("execute", new String[] { "org.apache.http.HttpHost", "org.apache.http.HttpRequest", "org.apache.http.client.ResponseHandler", "org.apache.http.protocol.HttpContext" }, interceptor); + + return aClass.toBytecode(); + } +} \ No newline at end of file diff --git a/src/main/java/com/profiler/modifier/arcus/interceptors/ExecuteMethodInterceptor.java b/src/main/java/com/profiler/modifier/arcus/interceptors/ExecuteMethodInterceptor.java new file mode 100644 index 000000000..36af18758 --- /dev/null +++ b/src/main/java/com/profiler/modifier/arcus/interceptors/ExecuteMethodInterceptor.java @@ -0,0 +1,22 @@ +package com.profiler.modifier.arcus.interceptors; + +import com.profiler.StopWatch; +import com.profiler.context.Annotation; +import com.profiler.context.Trace; +import com.profiler.interceptor.StaticAroundInterceptor; + +public class ExecuteMethodInterceptor implements StaticAroundInterceptor { + + @Override + public void before(Object target, String className, String methodName, Object[] args) { + System.out.println("\n\n\n\nARCUS BEFORE"); + + StopWatch.start("ExecuteMethodInterceptor"); + } + + @Override + public void after(Object target, String className, String methodName, Object[] args, Object result) { + System.out.println("\n\n\n\nARCUS AFTER"); + Trace.record(new Annotation.ClientRecv(), StopWatch.stopAndGetElapsed("ExecuteMethodInterceptor")); + } +} \ No newline at end of file diff --git a/src/main/java/com/profiler/modifier/db/mysql/MySQLPreparedStatementModifier.java b/src/main/java/com/profiler/modifier/db/mysql/MySQLPreparedStatementModifier.java index f9828daa6..d0490cee0 100644 --- a/src/main/java/com/profiler/modifier/db/mysql/MySQLPreparedStatementModifier.java +++ b/src/main/java/com/profiler/modifier/db/mysql/MySQLPreparedStatementModifier.java @@ -97,6 +97,6 @@ public class MySQLPreparedStatementModifier extends AbstractModifier { private void updateExecuteQueryMethod(CtClass cc) throws Exception { CtMethod method = cc.getDeclaredMethod("executeQuery", null); - method.insertAfter("{" + DatabaseRequestTracer.FQCN + ".put(" + TomcatProfilerConstant.REQ_DATA_TYPE_DB_EXECUTE_QUERY + "); }"); + method.insertAfter("{System.out.println(\"EXECUTE QUERY\");" + DatabaseRequestTracer.FQCN + ".put(" + TomcatProfilerConstant.REQ_DATA_TYPE_DB_EXECUTE_QUERY + "); }"); } } 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 fa96a6e4a..d9306afa5 100644 --- a/src/main/java/com/profiler/modifier/db/mysql/MySQLStatementModifier.java +++ b/src/main/java/com/profiler/modifier/db/mysql/MySQLStatementModifier.java @@ -5,15 +5,10 @@ import java.util.logging.Level; import java.util.logging.Logger; import javassist.ByteArrayClassPath; -import javassist.CtClass; -import javassist.CtMethod; -import com.profiler.config.TomcatProfilerConstant; -import com.profiler.interceptor.Interceptor; import com.profiler.interceptor.bci.ByteCodeInstrumentor; import com.profiler.interceptor.bci.InstrumentClass; import com.profiler.modifier.AbstractModifier; -import com.profiler.trace.DatabaseRequestTracer; public class MySQLStatementModifier extends AbstractModifier { @@ -31,54 +26,22 @@ public class MySQLStatementModifier extends AbstractModifier { if (logger.isLoggable(Level.INFO)) { logger.info("Modifing. " + javassistClassName); } - // checkLibrary(classLoader, javassistClassName); - - Interceptor interceptor = newInterceptor(classLoader, protectedDomain, "com.profiler.modifier.db.mysql.interceptors.ExecuteQueryMethodInterceptor"); - if (interceptor == null) { - return null; - } byteCodeInstrumentor.checkLibrary(classLoader, javassistClassName); classPool.insertClassPath(new ByteArrayClassPath(javassistClassName, classFileBuffer)); InstrumentClass aClass = byteCodeInstrumentor.getClass(javassistClassName); - aClass.addInterceptor("executeQuery", new String[] { "java.lang.String" }, interceptor); + + boolean instrumented = aClass.addInterceptor("executeQuery", new String[] { "java.lang.String" }, newInterceptor(classLoader, protectedDomain, "com.profiler.modifier.db.mysql.interceptors.ExecuteQueryMethodInterceptor")); + + instrumented &= aClass.addInterceptor("executeUpdate", new String[] { "java.lang.String", "boolean", "boolean" }, newInterceptor(classLoader, protectedDomain, "com.profiler.modifier.db.mysql.interceptors.ExecuteUpdateMethodInterceptor")); + + System.out.println("instrumented=" + instrumented); + + if (!instrumented) { + return null; + } return aClass.toBytecode(); - - // return changeMethod(javassistClassName, classFileBuffer); - } - - @Deprecated - private byte[] changeMethod(String javassistClassName, byte[] classfileBuffer) { - try { - CtClass cc = classPool.get(javassistClassName); - - updateExecuteQueryMethod(cc); - - printClassConvertComplete(javassistClassName); - - return cc.toBytecode(); - } catch (Exception e) { - if (logger.isLoggable(Level.WARNING)) { - logger.log(Level.WARNING, e.getMessage(), e); - } - } - return null; - } - - @Deprecated - private void updateExecuteQueryMethod(CtClass cc) throws Exception { - CtClass[] params = new CtClass[1]; - params[0] = classPool.getCtClass("java.lang.String"); - CtMethod method = cc.getDeclaredMethod("executeQuery", params); - - StringBuilder sb = new StringBuilder(); - sb.append("{"); - sb.append(DatabaseRequestTracer.FQCN + ".putSqlQuery(" + TomcatProfilerConstant.REQ_DATA_TYPE_DB_QUERY + ",$1);"); - sb.append(DatabaseRequestTracer.FQCN + ".put(" + TomcatProfilerConstant.REQ_DATA_TYPE_DB_EXECUTE_QUERY + ");"); - sb.append("}"); - - method.insertAfter(sb.toString()); } } \ No newline at end of file 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 5065798c1..d9ec5c295 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 @@ -15,9 +15,21 @@ public class ExecuteQueryMethodInterceptor implements StaticAroundInterceptor { @Override public void before(Object target, String className, String methodName, Object[] args) { try { + /** + * If method was not called by request handler, we skip tagging. + */ + if (Trace.getCurrentTraceId() == null) { + return; + } + Trace.recordRpcName("mysql", ""); + // + // TODO: add destination address + // + if (args.length > 0) { + System.out.println("Query=" + args[0]); Trace.record("Query=" + args[0]); } @@ -31,6 +43,10 @@ public class ExecuteQueryMethodInterceptor implements StaticAroundInterceptor { @Override public void after(Object target, String className, String methodName, Object[] args, Object result) { + if (Trace.getCurrentTraceId() == null) { + return; + } + Trace.record(new Annotation.ClientRecv(), StopWatch.stopAndGetElapsed("ExecuteQueryMethodInterceptor")); } } diff --git a/src/main/java/com/profiler/modifier/db/mysql/interceptors/ExecuteUpdateMethodInterceptor.java b/src/main/java/com/profiler/modifier/db/mysql/interceptors/ExecuteUpdateMethodInterceptor.java new file mode 100644 index 000000000..964ddacef --- /dev/null +++ b/src/main/java/com/profiler/modifier/db/mysql/interceptors/ExecuteUpdateMethodInterceptor.java @@ -0,0 +1,55 @@ +package com.profiler.modifier.db.mysql.interceptors; + +import com.profiler.StopWatch; +import com.profiler.context.Annotation; +import com.profiler.context.Trace; +import com.profiler.interceptor.StaticAroundInterceptor; + +/** + * protected int executeUpdate(String sql, boolean isBatch, boolean + * returnGeneratedKeys) + * + * @author netspider + * + */ +public class ExecuteUpdateMethodInterceptor implements StaticAroundInterceptor { + + @Override + public void before(Object target, String className, String methodName, Object[] args) { + System.out.println("ExecuteUpdateMethodInterceptor.before"); + try { + /** + * If method was not called by request handler, we skip tagging. + */ + if (Trace.getCurrentTraceId() == null) { + return; + } + + Trace.recordRpcName("mysql", ""); + + // + // TODO: add destination address + // + + if (args.length > 0) { + Trace.record("Query=" + args[0]); + } + + Trace.record(new Annotation.ClientSend()); + + StopWatch.start("ExecuteUpdateMethodInterceptor"); + } catch (Exception e) { + e.printStackTrace(); + } + } + + @Override + public void after(Object target, String className, String methodName, Object[] args, Object result) { + System.out.println("ExecuteUpdateMethodInterceptor.after"); + if (Trace.getCurrentTraceId() == null) { + return; + } + + Trace.record(new Annotation.ClientRecv(), StopWatch.stopAndGetElapsed("ExecuteUpdateMethodInterceptor")); + } +}