From c9bc6e8236ea158660ddf660c51b6bbab5f2a700 Mon Sep 17 00:00:00 2001 From: Woonduk Kang Date: Wed, 14 Nov 2012 07:50:03 +0000 Subject: [PATCH] =?UTF-8?q?[=EA=B0=95=EC=9A=B4=EB=8D=95]=20[LUCYSUS-1744]?= =?UTF-8?q?=20arcus=20=EB=B9=84=EB=8F=99=EA=B8=B0=20=EC=B6=94=EC=A0=81?= =?UTF-8?q?=EC=8B=9C=20=EB=B3=84=EB=8F=84=20global=20map=EC=97=90=20?= =?UTF-8?q?=EB=93=B1=EB=A1=9D=EB=90=98=EC=A7=80=20=EC=95=8A=EA=B3=A0=20?= =?UTF-8?q?=ED=8A=B8=EB=A0=88=EC=9D=B4=EC=8A=A4=20=EA=B0=9D=EC=B2=B4?= =?UTF-8?q?=EC=97=90=EB=A7=8C=20attatch=EB=90=98=EC=84=9C=20=EB=8F=99?= =?UTF-8?q?=EC=9E=91=ED=95=98=EB=8F=84=EB=A1=9D=20=EB=B3=80=EA=B2=BD.?= 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@863 84d0f5b1-2673-498c-a247-62c4ff18d310 --- .../java/com/profiler/context/AsyncTrace.java | 30 ++++++++------- .../com/profiler/context/GlobalCallTrace.java | 2 +- src/main/java/com/profiler/context/Trace.java | 8 ++++ .../modifier/arcus/ArcusClientModifier.java | 2 +- .../BaseOperationCancelInterceptor.java | 26 ++++++++----- ...seOperationTransitionStateInterceptor.java | 38 +++++++++++++------ .../interceptors/ConstructInterceptor.java | 18 ++++----- .../ExecuteMethodInterceptor.java | 3 +- 8 files changed, 79 insertions(+), 48 deletions(-) diff --git a/src/main/java/com/profiler/context/AsyncTrace.java b/src/main/java/com/profiler/context/AsyncTrace.java index 9410c4bc1..037060ed1 100644 --- a/src/main/java/com/profiler/context/AsyncTrace.java +++ b/src/main/java/com/profiler/context/AsyncTrace.java @@ -20,11 +20,11 @@ public class AsyncTrace { // 비동기일 경우 traceenable의 경우 애매함. span을 보내는것으로 데이터를 생성하므로 약간 이상. // private boolean tracingEnabled; - private static int COMPLATE_STATE_NONE = 0; - private static int COMPLATE_STATE_FIRE = 1; - private static int COMPLATE_STATE_TIMEOUT = 2; + public static final int STATE_INIT = 0; + public static final int STATE_FIRE = 1; + public static final int STATE_TIMEOUT = 2; - private final AtomicInteger complate = new AtomicInteger(COMPLATE_STATE_NONE); + private final AtomicInteger state = new AtomicInteger(STATE_INIT); private int asyncId; private Span span; @@ -67,9 +67,6 @@ public class AsyncTrace { public void record(Annotation annotation) { - if (complate.get() == COMPLATE_STATE_FIRE) { - - } annotate(annotation.getCode(), null); } @@ -96,7 +93,6 @@ public class AsyncTrace { } public void recordRpcName(final String service, final String rpc) { - try { this.span.setServiceName(service); this.span.setName(rpc); @@ -151,22 +147,28 @@ public class AsyncTrace { } this.dataSender.send(span.toThrift()); -// span.cancelTimer(); } catch (Exception e) { logger.log(Level.SEVERE, e.getMessage(), e); } } + public int getState() { + return state.get(); + } + public void timeout() { - if (complate.compareAndSet(0, COMPLATE_STATE_TIMEOUT)) { - // TODO timeout log 던지기. + if (state.compareAndSet(0, STATE_TIMEOUT)) { + // TODO timeout span log 던지기. // 뭘 어떤 내용을 던져야 되는지 아직 모르겠음???? } } - public boolean cancelTimeout() { - if (complate.compareAndSet(0, COMPLATE_STATE_FIRE)) { - this.timeoutTask.cancel(); + public boolean fire() { + if (state.compareAndSet(0, STATE_FIRE)) { + if (timeoutTask != null) { + // timeout이 걸려 있는 asynctrace일 경우 호출해 준다. + this.timeoutTask.cancel(); + } return true; } return false; diff --git a/src/main/java/com/profiler/context/GlobalCallTrace.java b/src/main/java/com/profiler/context/GlobalCallTrace.java index 091845576..371d9a2bd 100644 --- a/src/main/java/com/profiler/context/GlobalCallTrace.java +++ b/src/main/java/com/profiler/context/GlobalCallTrace.java @@ -49,7 +49,7 @@ public class GlobalCallTrace { public AsyncTrace removeTraceObject(int asyncId) { AsyncTrace asyncTrace = trace.remove(asyncId); if (asyncTrace != null) { - boolean result = asyncTrace.cancelTimeout(); + boolean result = asyncTrace.fire(); if (!result) { // 이미 timeout된 asyncTrace임. return null; diff --git a/src/main/java/com/profiler/context/Trace.java b/src/main/java/com/profiler/context/Trace.java index d075e3e33..264c1706d 100644 --- a/src/main/java/com/profiler/context/Trace.java +++ b/src/main/java/com/profiler/context/Trace.java @@ -66,6 +66,14 @@ public final class Trace { } } + public AsyncTrace createAsyncTrace() { + TraceID nextTraceId = getNextTraceId(); + Span span = new Span(nextTraceId, null, null); + AsyncTrace asyncTrace = new AsyncTrace(span); + asyncTrace.setDataSender(this.getDataSender()); + return asyncTrace; + } + private StackFrame createStackFrame(TraceID nextId, int stackId) { StackFrame stackFrame = new StackFrame(); stackFrame.setStackFrameId(stackId); diff --git a/src/main/java/com/profiler/modifier/arcus/ArcusClientModifier.java b/src/main/java/com/profiler/modifier/arcus/ArcusClientModifier.java index 96a5283b8..0f68a7183 100644 --- a/src/main/java/com/profiler/modifier/arcus/ArcusClientModifier.java +++ b/src/main/java/com/profiler/modifier/arcus/ArcusClientModifier.java @@ -33,7 +33,7 @@ public class ArcusClientModifier extends AbstractModifier { try { InstrumentClass aClass = byteCodeInstrumentor.getClass(javassistClassName); - aClass.addTraceVariable("__asyncTraceId", "__setAsyncTraceId", "__getAsyncTraceId", "int"); + aClass.addTraceVariable("__asyncTraceId", "__setAsyncTraceId", "__getAsyncTraceId", "java.lang.Object"); aClass.addConstructorInterceptor(null, new ConstructInterceptor()); Interceptor transitionStateInterceptor = newInterceptor(classLoader, protectedDomain, "com.profiler.modifier.arcus.interceptors.BaseOperationTransitionStateInterceptor"); diff --git a/src/main/java/com/profiler/modifier/arcus/interceptors/BaseOperationCancelInterceptor.java b/src/main/java/com/profiler/modifier/arcus/interceptors/BaseOperationCancelInterceptor.java index 804bea10a..f00819799 100644 --- a/src/main/java/com/profiler/modifier/arcus/interceptors/BaseOperationCancelInterceptor.java +++ b/src/main/java/com/profiler/modifier/arcus/interceptors/BaseOperationCancelInterceptor.java @@ -1,9 +1,6 @@ package com.profiler.modifier.arcus.interceptors; import com.profiler.context.AsyncTrace; -import com.profiler.context.GlobalCallTrace; -import com.profiler.context.TraceContext; -import com.profiler.interceptor.StaticAfterInterceptor; import com.profiler.interceptor.StaticBeforeInterceptor; import com.profiler.util.MetaObject; import com.profiler.util.StringUtils; @@ -17,8 +14,9 @@ import java.util.logging.Logger; * */ public class BaseOperationCancelInterceptor implements StaticBeforeInterceptor { + private final Logger logger = Logger.getLogger(BaseOperationCancelInterceptor.class.getName()); - private MetaObject asyncTraceId = new MetaObject("__getAsyncTraceId", null); + private MetaObject asyncTraceId = new MetaObject("__getAsyncTraceId"); @Override public void before(Object target, String className, String methodName, String parameterDescription, Object[] args) { @@ -26,18 +24,26 @@ public class BaseOperationCancelInterceptor implements StaticBeforeInterceptor { logger.info("before " + StringUtils.toString(target) + " " + className + "." + methodName + parameterDescription + " args:" + Arrays.toString(args)); } - TraceContext traceContext = TraceContext.getTraceContext(); - GlobalCallTrace globalCallTrace = traceContext.getGlobalCallTrace(); + Object asyncId = asyncTraceId.invoke(target); if (asyncId == null) { - logger.fine("asyncId not found"); + logger.fine("asyncId not found id:" + asyncId); return; } - AsyncTrace asyncTrace = globalCallTrace.getTraceObject((Integer) asyncId); - if (asyncTrace == null) { - logger.fine("asyncTrace expired"); + +// TraceContext traceContext = TraceContext.getTraceContext(); +// GlobalCallTrace globalCallTrace = traceContext.getGlobalCallTrace(); +// AsyncTrace asyncTrace = globalCallTrace.getTraceObject((Integer) asyncId); +// if (asyncTrace == null) { +// logger.fine("asyncTrace expired"); +// return; +// } + AsyncTrace asyncTrace = (AsyncTrace) asyncId; + if (asyncTrace.getState() != AsyncTrace.STATE_INIT) { + // 이미 동작 완료된 상태임. return; } + BaseOperationImpl baseOperation = (BaseOperationImpl) target; if (!baseOperation.isCancelled()) { TimeObject timeObject = (TimeObject) asyncTrace.getAttachObject(); diff --git a/src/main/java/com/profiler/modifier/arcus/interceptors/BaseOperationTransitionStateInterceptor.java b/src/main/java/com/profiler/modifier/arcus/interceptors/BaseOperationTransitionStateInterceptor.java index 20e855851..9ead6054c 100644 --- a/src/main/java/com/profiler/modifier/arcus/interceptors/BaseOperationTransitionStateInterceptor.java +++ b/src/main/java/com/profiler/modifier/arcus/interceptors/BaseOperationTransitionStateInterceptor.java @@ -2,9 +2,7 @@ package com.profiler.modifier.arcus.interceptors; import com.profiler.context.Annotation; import com.profiler.context.AsyncTrace; -import com.profiler.context.GlobalCallTrace; import com.profiler.context.TraceContext; -import com.profiler.interceptor.StaticAfterInterceptor; import com.profiler.interceptor.StaticBeforeInterceptor; import com.profiler.util.InterceptorUtils; import com.profiler.util.MetaObject; @@ -16,6 +14,7 @@ import net.spy.memcached.protocol.BaseOperationImpl; import java.net.InetSocketAddress; import java.net.SocketAddress; import java.nio.ByteBuffer; +import java.nio.charset.Charset; import java.util.Arrays; import java.util.logging.Level; import java.util.logging.Logger; @@ -26,7 +25,10 @@ import java.util.logging.Logger; public class BaseOperationTransitionStateInterceptor implements StaticBeforeInterceptor { private final Logger logger = Logger.getLogger(BaseOperationTransitionStateInterceptor.class.getName()); - private MetaObject asyncTraceId = new MetaObject("__getAsyncTraceId"); + + private static final Charset UTF8 = Charset.forName("UTF-8"); + + private MetaObject asyncTraceId = new MetaObject("__getAsyncTraceId"); @Override public void before(Object target, String className, String methodName, String parameterDescription, Object[] args) { @@ -34,19 +36,22 @@ public class BaseOperationTransitionStateInterceptor implements StaticBeforeInte logger.info("before " + StringUtils.toString(target) + " " + className + "." + methodName + parameterDescription + " args:" + Arrays.toString(args)); } TraceContext traceContext = TraceContext.getTraceContext(); - GlobalCallTrace globalCallTrace = traceContext.getGlobalCallTrace(); +// GlobalCallTrace globalCallTrace = traceContext.getGlobalCallTrace(); Object asyncId = asyncTraceId.invoke(target); if (asyncId == null) { logger.fine("asyncId not found"); return; } - // saynctrace를 제거한다. - AsyncTrace asyncTrace = globalCallTrace.removeTraceObject((Integer) asyncId); - if (asyncTrace == null) { - logger.fine("AsyncTrace already timeout"); - return; - } + +// AsyncTrace asyncTrace = globalCallTrace.getTraceObject((Integer) asyncId); +// if (asyncTrace == null) { +// logger.fine("AsyncTrace already timeout"); +// return; +// } + System.out.println(asyncId); + AsyncTrace asyncTrace = (AsyncTrace) asyncId; + OperationState newState = (OperationState) args[0]; BaseOperationImpl baseOperation = (BaseOperationImpl) target; @@ -54,6 +59,9 @@ public class BaseOperationTransitionStateInterceptor implements StaticBeforeInte if (logger.isLoggable(Level.FINE)) { logger.fine("event:" + newState + " asyncId:" + asyncId); } + if (asyncTrace.getState() != AsyncTrace.STATE_INIT) { + return; + } MemcachedNode handlingNode = baseOperation.getHandlingNode(); SocketAddress socketAddress = handlingNode.getSocketAddress(); if (socketAddress instanceof InetSocketAddress) { @@ -73,6 +81,11 @@ public class BaseOperationTransitionStateInterceptor implements StaticBeforeInte if (logger.isLoggable(Level.FINE)) { logger.fine("event:" + newState + " asyncId:" + asyncId); } + boolean fire = asyncTrace.fire(); + if (!fire) { + return; + } +// globalCallTrace.removeTraceObject((Integer) asyncId); Exception exception = baseOperation.getException(); if (exception != null) { asyncTrace.recordAttibute("exception", InterceptorUtils.exceptionToString(exception)); @@ -93,8 +106,9 @@ public class BaseOperationTransitionStateInterceptor implements StaticBeforeInte if (buffer == null) { return "UNKNOWN"; } - // TODO 기본 인코딩은 뭔가? 동시성은 괜찮은건가? buffer 사이즈의 compact는 되어있는것인가. - return new String(buffer.array()); + System.out.println(buffer.array().length + " po:" + buffer.position() + " limit:" + buffer.limit() + " remaining" + + buffer.remaining() + " aoffset:" + buffer.arrayOffset()); + return new String(buffer.array(), UTF8); } diff --git a/src/main/java/com/profiler/modifier/arcus/interceptors/ConstructInterceptor.java b/src/main/java/com/profiler/modifier/arcus/interceptors/ConstructInterceptor.java index ba096f5d6..ff4f87cb9 100644 --- a/src/main/java/com/profiler/modifier/arcus/interceptors/ConstructInterceptor.java +++ b/src/main/java/com/profiler/modifier/arcus/interceptors/ConstructInterceptor.java @@ -15,7 +15,9 @@ import java.util.logging.Logger; public class ConstructInterceptor implements StaticAfterInterceptor { private final Logger logger = Logger.getLogger(ConstructInterceptor.class.getName()); - private MetaObject asyncTraceId = new MetaObject("__setAsyncTraceId", int.class); + // private MetaObject asyncTraceId = new MetaObject("__setAsyncTraceId", int.class); + private MetaObject asyncTraceId = new MetaObject("__setAsyncTraceId", Object.class); + @Override public void after(Object target, String className, String methodName, String parameterDescription, Object[] args, Object result) { @@ -27,15 +29,13 @@ public class ConstructInterceptor implements StaticAfterInterceptor { if (trace == null) { return; } - GlobalCallTrace globalCallTrace = traceContext.getGlobalCallTrace(); - - TraceID nextTraceId = trace.getNextTraceId(); - Span span = new Span(nextTraceId, null, null); - AsyncTrace asyncTrace = new AsyncTrace(span); + AsyncTrace asyncTrace = trace.createAsyncTrace(); asyncTrace.setAttachObject(new TimeObject()); - int asyncId = globalCallTrace.registerTraceObject(asyncTrace); - - asyncTraceId.invoke(target, asyncId); +// GlobalCallTrace globalCallTrace = traceContext.getGlobalCallTrace(); +// int asyncId = globalCallTrace.registerTraceObject(asyncTrace); +// +// asyncTraceId.invoke(target, asyncId); + asyncTraceId.invoke(target, asyncTrace); } } diff --git a/src/main/java/com/profiler/modifier/connector/interceptors/ExecuteMethodInterceptor.java b/src/main/java/com/profiler/modifier/connector/interceptors/ExecuteMethodInterceptor.java index 6362fb08e..032de5755 100644 --- a/src/main/java/com/profiler/modifier/connector/interceptors/ExecuteMethodInterceptor.java +++ b/src/main/java/com/profiler/modifier/connector/interceptors/ExecuteMethodInterceptor.java @@ -51,10 +51,11 @@ public class ExecuteMethodInterceptor implements StaticAroundInterceptor { request.addHeader(Header.HTTP_SAMPLED.toString(), String.valueOf(nextId.isSampled())); request.addHeader(Header.HTTP_FLAGS.toString(), String.valueOf(nextId.getFlags())); + trace.record(Annotation.ClientSend); trace.recordRpcName(request.getProtocolVersion().toString(), "CLIENT"); trace.recordEndPoint(request.getProtocolVersion().toString() + ":" + host.getHostName() + ":" + host.getPort()); trace.recordAttribute("http.url", request.getRequestLine().getUri()); - trace.record(Annotation.ClientSend); + }