From 35f249f08a2f9b8fc09cf08d8bca29517543e847 Mon Sep 17 00:00:00 2001 From: Chisu Yu Date: Wed, 6 Mar 2013 10:04:58 +0000 Subject: [PATCH] =?UTF-8?q?[=EC=9C=A0=EC=B9=98=EC=88=98]=20[NOBTS]=20sun.n?= =?UTF-8?q?et.www.protocol.http.HttpURLConnection=20modifier=EC=B6=94?= =?UTF-8?q?=EA=B0=80.=20(=EB=8F=99=EC=9E=91=20=EC=95=88=ED=95=A8.)?= 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@1299 84d0f5b1-2673-498c-a247-62c4ff18d310 --- .../connector/HttpURLConnectionModifier.java | 47 ++++++++++ .../ConnectMethodInterceptor.java | 91 +++++++++++++++++++ 2 files changed, 138 insertions(+) create mode 100644 src/main/java/com/profiler/modifier/connector/HttpURLConnectionModifier.java create mode 100644 src/main/java/com/profiler/modifier/connector/interceptors/ConnectMethodInterceptor.java diff --git a/src/main/java/com/profiler/modifier/connector/HttpURLConnectionModifier.java b/src/main/java/com/profiler/modifier/connector/HttpURLConnectionModifier.java new file mode 100644 index 000000000..5324322da --- /dev/null +++ b/src/main/java/com/profiler/modifier/connector/HttpURLConnectionModifier.java @@ -0,0 +1,47 @@ +package com.profiler.modifier.connector; + +import java.security.ProtectionDomain; +import java.util.logging.Level; +import java.util.logging.Logger; + +import com.profiler.Agent; +import com.profiler.interceptor.Interceptor; +import com.profiler.interceptor.bci.ByteCodeInstrumentor; +import com.profiler.interceptor.bci.InstrumentClass; +import com.profiler.interceptor.bci.InstrumentException; +import com.profiler.modifier.AbstractModifier; + +/** + * TODO classloader문제 있음. + * @author netspider + * + */ +public class HttpURLConnectionModifier extends AbstractModifier { + + private final Logger logger = Logger.getLogger(HTTPClientModifier.class.getName()); + + public HttpURLConnectionModifier(ByteCodeInstrumentor byteCodeInstrumentor, Agent agent) { + super(byteCodeInstrumentor, agent); + } + + public String getTargetClass() { + return "sun/net/www/protocol/http/HttpURLConnection"; + } + + public byte[] modify(ClassLoader classLoader, String javassistClassName, ProtectionDomain protectedDomain, byte[] classFileBuffer) { + if (logger.isLoggable(Level.INFO)) { + logger.info("Modifing. " + javassistClassName); + } + + byteCodeInstrumentor.checkLibrary(classLoader, javassistClassName); + try { + InstrumentClass aClass = byteCodeInstrumentor.getClass(javassistClassName); + Interceptor interceptor = byteCodeInstrumentor.newInterceptor(ClassLoader.getSystemClassLoader(), protectedDomain, "com.profiler.modifier.connector.interceptors.ConnectMethodInterceptor"); + aClass.addInterceptor("connect", null, interceptor); + return aClass.toBytecode(); + } catch (InstrumentException e) { + e.printStackTrace(); + return null; + } + } +} \ No newline at end of file diff --git a/src/main/java/com/profiler/modifier/connector/interceptors/ConnectMethodInterceptor.java b/src/main/java/com/profiler/modifier/connector/interceptors/ConnectMethodInterceptor.java new file mode 100644 index 000000000..043e9a092 --- /dev/null +++ b/src/main/java/com/profiler/modifier/connector/interceptors/ConnectMethodInterceptor.java @@ -0,0 +1,91 @@ +package com.profiler.modifier.connector.interceptors; + +import java.net.HttpURLConnection; +import java.util.logging.Logger; + +import com.profiler.common.AnnotationKey; +import com.profiler.common.ServiceType; +import com.profiler.context.Header; +import com.profiler.context.Trace; +import com.profiler.context.TraceContext; +import com.profiler.context.TraceID; +import com.profiler.interceptor.ByteCodeMethodDescriptorSupport; +import com.profiler.interceptor.MethodDescriptor; +import com.profiler.interceptor.StaticAroundInterceptor; +import com.profiler.logging.LoggingUtils; + +/** + * TODO classloader문제 있음. + * @author netspider + * + */ +public class ConnectMethodInterceptor implements StaticAroundInterceptor, ByteCodeMethodDescriptorSupport { + + private final Logger logger = Logger.getLogger(ConnectMethodInterceptor.class.getName()); + private final boolean isDebug = LoggingUtils.isDebug(logger); + + private MethodDescriptor descriptor; + + @Override + public void before(Object target, String className, String methodName, String parameterDescription, Object[] args) { + if (isDebug) { + LoggingUtils.logBefore(logger, target, className, methodName, parameterDescription, args); + } + TraceContext traceContext = TraceContext.getTraceContext(); + Trace trace = traceContext.currentTraceObject(); + if (trace == null) { + return; + } + trace.traceBlockBegin(); + trace.markBeforeTime(); + + TraceID nextId = trace.getTraceId().getNextTraceId(); + trace.recordNextSpanId(nextId.getSpanId()); + + HttpURLConnection request = (HttpURLConnection) target; + + // UUID format을 그대로. + request.setRequestProperty(Header.HTTP_TRACE_ID.toString(), nextId.getId().toString()); + request.setRequestProperty(Header.HTTP_SPAN_ID.toString(), Integer.toString(nextId.getSpanId())); + request.setRequestProperty(Header.HTTP_PARENT_SPAN_ID.toString(), Integer.toString(nextId.getParentSpanId())); + request.setRequestProperty(Header.HTTP_SAMPLED.toString(), String.valueOf(nextId.isSampled())); + request.setRequestProperty(Header.HTTP_FLAGS.toString(), String.valueOf(nextId.getFlags())); + + trace.recordServiceType(ServiceType.HTTP_CLIENT); + trace.recordRpcName("CLIENT"); + + String host = request.getURL().getHost(); + int port = request.getURL().getPort(); + + trace.recordEndPoint("HTTP/1.1:" + host + ((port > 0) ? ":" + port : "")); + trace.recordDestinationId(host + ((port > 0) ? ":" + port : "")); + + trace.recordAttribute(AnnotationKey.HTTP_URL, request.getURL().toString()); + } + + @Override + public void after(Object target, String className, String methodName, String parameterDescription, Object[] args, Object result) { + if (isDebug) { + // result는 로깅하지 않는다. + LoggingUtils.logAfter(logger, target, className, methodName, parameterDescription, args); + } + + TraceContext traceContext = TraceContext.getTraceContext(); + Trace trace = traceContext.currentTraceObject(); + if (trace == null) { + return; + } + trace.recordApi(descriptor); + trace.recordException(result); + + trace.markAfterTime(); + trace.traceBlockEnd(); + } + + @Override + public void setMethodDescriptor(MethodDescriptor descriptor) { + this.descriptor = descriptor; + TraceContext traceContext = TraceContext.getTraceContext(); + traceContext.cacheApi(descriptor); + } +} \ No newline at end of file