diff --git a/src/main/java/com/profiler/TomcatProfiler.java b/src/main/java/com/profiler/TomcatProfiler.java index 8ab27d068..dd55fd238 100644 --- a/src/main/java/com/profiler/TomcatProfiler.java +++ b/src/main/java/com/profiler/TomcatProfiler.java @@ -51,6 +51,14 @@ public class TomcatProfiler implements ClassFileTransformer { } // 이게 로드할 lib List임. List libUrlList = resolveLib(classPathResolver); + AgentClassLoader agentClassLoader = new AgentClassLoader(libUrlList.toArray(new URL[libUrlList.size()])); + agentClassLoader.setBootClass("com.profiler.boot.BootClassTest"); + try { + agentClassLoader.boot(); + } catch (Exception e) { + logger.info("test error"); + e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates. + } try { ProfilerConfig profilerConfig = readConfig(classPathResolver); diff --git a/src/main/java/com/profiler/context/DefaultTrace.java b/src/main/java/com/profiler/context/DefaultTrace.java new file mode 100644 index 000000000..099281ad0 --- /dev/null +++ b/src/main/java/com/profiler/context/DefaultTrace.java @@ -0,0 +1,437 @@ +package com.profiler.context; + +import com.profiler.common.AnnotationKey; +import com.profiler.common.ServiceType; +import com.profiler.common.util.ParsingResult; +import com.profiler.interceptor.MethodDescriptor; +import com.profiler.logging.LoggingUtils; +import com.profiler.util.StringUtils; + +import java.util.List; +import java.util.logging.Level; +import java.util.logging.Logger; + +/** + * @author netspider + */ +public final class DefaultTrace implements Trace { + + private static final Logger logger = Logger.getLogger(DefaultTrace.class.getName()); + private static final boolean isDebug = LoggingUtils.isDebug(logger); + + public static final int NOCHECK_STACKID = -1; + public static final int ROOT_STACKID = 0; + + private short sequence; + + private boolean tracingEnabled = true; + + private CallStack callStack; + + private Storage storage; + + private TraceContext traceContext; + + // use for calculating depth of each Span. + private int latestStackIndex = -1; + + public DefaultTrace() { + TraceID traceId = TraceID.newTraceId(); + this.callStack = new CallStack(traceId); + latestStackIndex = this.callStack.push(); + StackFrame stackFrame = createRootStackFrame(ROOT_STACKID, callStack.getSpan()); + this.callStack.setStackFrame(stackFrame); + } + + public DefaultTrace(TraceID continueRoot) { + // this.root = continueRoot; + this.callStack = new CallStack(continueRoot); + latestStackIndex = this.callStack.push(); + StackFrame stackFrame = createRootStackFrame(ROOT_STACKID, callStack.getSpan()); + this.callStack.setStackFrame(stackFrame); + } + + public CallStack getCallStack() { + return callStack; + } + + + public void setStorage(Storage storage) { + this.storage = storage; + } + + public short getSequence() { + return sequence++; + } + + @Override + public AsyncTrace createAsyncTrace() { + // 경우에 따라 별도 timeout 처리가 있어야 될수도 있음. + SpanEvent spanEvent = new SpanEvent(callStack.getSpan()); + spanEvent.setSequence(getSequence()); + AsyncTrace asyncTrace = new AsyncTrace(spanEvent); + // asyncTrace.setDataSender(this.getDataSender()); + asyncTrace.setStorage(this.storage); + return asyncTrace; + } + + private StackFrame createSubStackFrame(int stackId) { + SpanEvent spanEvent = new SpanEvent(callStack.getSpan()); + SubStackFrame stackFrame = new SubStackFrame(spanEvent); + stackFrame.setStackFrameId(stackId); + stackFrame.setSequence(getSequence()); + return stackFrame; + } + + private StackFrame createRootStackFrame(int stackId, Span span) { + RootStackFrame stackFrame = new RootStackFrame(span); + stackFrame.setStackFrameId(stackId); + stackFrame.setSpan(span); + stackFrame.setStackFrameId(ROOT_STACKID); + return stackFrame; + } + + @Override + public void traceBlockBegin() { + traceBlockBegin(NOCHECK_STACKID); + } + + @Override + public void markBeforeTime() { + StackFrame stackFrame = getCurrentStackFrame(); + stackFrame.markBeforeTime(); + } + + @Override + public long getBeforeTime() { + StackFrame stackFrame = getCurrentStackFrame(); + return stackFrame.getBeforeTime(); + } + + @Override + public void markAfterTime() { + StackFrame stackFrame = getCurrentStackFrame(); + stackFrame.markAfterTime(); + } + + @Override + public long getAfterTime() { + StackFrame stackFrame = getCurrentStackFrame(); + return stackFrame.getAfterTime(); + } + + + @Override + public void traceBlockBegin(int stackId) { + int currentStackIndex = callStack.push(); + StackFrame stackFrame = createSubStackFrame(stackId); + + if (latestStackIndex != currentStackIndex) { + latestStackIndex = currentStackIndex; + SpanEvent spanEvent = ((SubStackFrame) stackFrame).getSpanEvent(); + spanEvent.setDepth(latestStackIndex); + } + + callStack.setStackFrame(stackFrame); + } + + @Override + public void traceRootBlockEnd() { + traceBlockEnd(ROOT_STACKID); + } + + @Override + public void traceBlockEnd() { + traceBlockEnd(NOCHECK_STACKID); + } + + + @Override + public void traceBlockEnd(int stackId) { + StackFrame currentStackFrame = callStack.getCurrentStackFrame(); + int stackFrameId = currentStackFrame.getStackFrameId(); + if (stackFrameId != stackId) { + // 자체 stack dump를 하면 오류발견이 쉬울것으로 생각됨 + if (logger.isLoggable(Level.WARNING)) { + logger.warning("Corrupted CallStack found. StackId not matched. expected:" + stackId + " current:" + stackFrameId); + } + } + if (currentStackFrame instanceof RootStackFrame) { + logSpan(((RootStackFrame) currentStackFrame).getSpan()); + } else { + logSpan(((SubStackFrame) currentStackFrame).getSpanEvent()); + } + callStack.pop(); + } + + public StackFrame getCurrentStackFrame() { + return callStack.getCurrentStackFrame(); + } + + /** + * Get current TraceID. If it was not set this will return null. + * + * @return + */ + @Override + public TraceID getTraceId() { + return callStack.getSpan().getTraceID(); + } + + @Override + public void enable() { + tracingEnabled = true; + } + + @Override + public void disable() { + tracingEnabled = false; + } + + void logSpan(SpanEvent spanEvent) { + if (isDebug) { + Thread th = Thread.currentThread(); + logger.fine("[WRITE SpanEvent]" + spanEvent + ", Thread ID=" + th.getId() + " Name=" + th.getName()); + } + this.storage.store(spanEvent); + } + + void logSpan(Span span) { + if (isDebug) { + Thread th = Thread.currentThread(); + logger.info("[WRITE SPAN]" + span + ", Thread ID=" + th.getId() + " Name=" + th.getName()); + } + this.storage.store(span); + } + + @Override + public void recordException(Object result) { + if (result instanceof Throwable) { + Throwable th = (Throwable) result; + String drop = StringUtils.drop(th.getMessage(), 256); + recordAttribute(AnnotationKey.EXCEPTION, drop); + + Span span = getCallStack().getSpan(); + if (span.getException() == 0) { + span.setException(1); + } + } + } + + @Override + public void recordApi(MethodDescriptor methodDescriptor) { + if (methodDescriptor == null) { + return; + } + if (methodDescriptor.getApiId() == 0) { + recordAttribute(AnnotationKey.API, methodDescriptor.getFullName()); + } else { + recordAttribute(AnnotationKey.API_DID, methodDescriptor.getApiId()); + } + } + + @Override + public void recordApi(MethodDescriptor methodDescriptor, Object[] args) { + // API 저장 방법의 개선 필요. + recordApi(methodDescriptor); + recocordArgs(args); + } + + @Override + public void recordApi(int apiId) { + recordAttribute(AnnotationKey.API_ID, apiId); + } + + @Override + public void recordApi(int apiId, Object[] args) { + recordAttribute(AnnotationKey.API_ID, apiId); + recocordArgs(args); + } + + private void recocordArgs(Object[] args) { + if (args != null) { + int min = Math.min(args.length, AnnotationKey.MAX_ARGS_SIZE); + for (int i = 0; i < min; i++) { + recordAttribute(AnnotationKey.getArgs(i), args[i]); + } + // TODO MAX 사이즈를 넘는건 마크만 해줘야 하나? + } + } + + + @Override + public void recordAttribute(final AnnotationKey key, final String value) { + recordAttribute(key, (Object) value); + } + + @Override + public ParsingResult recordSqlInfo(String sql) { + if (sql == null) { + return null; + } + ParsingResult parsingResult = traceContext.parseSql(sql); + recordSqlParsingResult(parsingResult); + return parsingResult; + } + + @Override + public void recordSqlParsingResult(ParsingResult parsingResult) { + recordAttribute(AnnotationKey.SQL_ID, parsingResult.getSql().hashCode()); + String output = parsingResult.getOutput(); + if (output != null && output.length() != 0) { + recordAttribute(AnnotationKey.SQL_PARAM, output); + } + } + + @Override + public void recordAttribute(final AnnotationKey key, final Object value) { + // TODO API 단일화 필요. + StackFrame currentStackFrame = getCurrentStackFrame(); + if (currentStackFrame instanceof RootStackFrame) { + Span span = ((RootStackFrame) currentStackFrame).getSpan(); + span.addAnnotation(new Annotation(key, value)); + } else { + SpanEvent spanEvent = ((SubStackFrame) currentStackFrame).getSpanEvent(); + spanEvent.addAnnotation(new Annotation(key, value)); + } + + } + + + @Override + public void recordServiceType(final ServiceType serviceType) { + // TODO API 단일화 필요. + StackFrame currentStackFrame = getCurrentStackFrame(); + if (currentStackFrame instanceof RootStackFrame) { + Span span = ((RootStackFrame) currentStackFrame).getSpan(); + span.setServiceType(serviceType); + } else { + SpanEvent spanEvent = ((SubStackFrame) currentStackFrame).getSpanEvent(); + spanEvent.setServiceType(serviceType); + } + + } + + @Override + public void recordRpcName(final String rpc) { + // TODO API 단일화 필요. + StackFrame currentStackFrame = getCurrentStackFrame(); + if (currentStackFrame instanceof RootStackFrame) { + Span span = ((RootStackFrame) currentStackFrame).getSpan(); + span.setRpc(rpc); + } else { + SpanEvent spanEvent = ((SubStackFrame) currentStackFrame).getSpanEvent(); + spanEvent.setRpc(rpc); + } + + } + + @Override + public void recordDestinationId(final String destinationId) { + // TODO API 단일화 필요. + StackFrame currentStackFrame = getCurrentStackFrame(); + if (currentStackFrame instanceof SubStackFrame) { + SpanEvent spanEvent = ((SubStackFrame) currentStackFrame).getSpanEvent(); + spanEvent.setDestionationId(destinationId); + } + } + + @Override + public void recordDestinationAddress(List address) { + // TODO API 단일화 필요. + StackFrame currentStackFrame = getCurrentStackFrame(); + if (currentStackFrame instanceof SubStackFrame) { + SpanEvent spanEvent = ((SubStackFrame) currentStackFrame).getSpanEvent(); + spanEvent.setDestinationAddress(); + } + } + + @Override + public void recordDestinationAddressList(List addressList) { + //To change body of created methods use File | Settings | File Templates. + } + + @Override + public void recordEndPoint(final String endPoint) { + // TODO API 단일화 필요. + StackFrame currentStackFrame = getCurrentStackFrame(); + if (currentStackFrame instanceof RootStackFrame) { + Span span = ((RootStackFrame) currentStackFrame).getSpan(); + span.setEndPoint(endPoint); + } else { + SpanEvent spanEvent = ((SubStackFrame) currentStackFrame).getSpanEvent(); + spanEvent.setEndPoint(endPoint); + } + } + + @Override + public void recordRemoteAddr(final String remoteAddr) { + // TODO API 단일화 필요. + StackFrame currentStackFrame = getCurrentStackFrame(); + if (currentStackFrame instanceof RootStackFrame) { + Span span = ((RootStackFrame) currentStackFrame).getSpan(); + span.setRemoteAddr(remoteAddr); + } else { + // do nothing. + } + } + + @Override + public void recordNextSpanId(int spanId) { + StackFrame currentStackFrame = getCurrentStackFrame(); + if (currentStackFrame instanceof RootStackFrame) { + logger.log(Level.WARNING, "OMG. Something's going wrong. Current stackframe is root Span. nextSpanId={}", spanId); + } else { + SpanEvent spanEvent = ((SubStackFrame) currentStackFrame).getSpanEvent(); + spanEvent.setNextSpanId(spanId); + } + } + + private void annotate(final AnnotationKey key) { + StackFrame currentStackFrame = getCurrentStackFrame(); + if (currentStackFrame instanceof RootStackFrame) { + Span span = ((RootStackFrame) currentStackFrame).getSpan(); + span.addAnnotation(new Annotation(key)); + } else { + SpanEvent spanEvent = ((SubStackFrame) currentStackFrame).getSpanEvent(); + spanEvent.addAnnotation(new Annotation(key)); + } + + } + + @Override + public void setTraceContext(TraceContext traceContext) { + this.traceContext = traceContext; + } + + @Override + public void recordParentApplication(String parentApplicationName, short parentApplicationType) { + StackFrame currentStackFrame = getCurrentStackFrame(); + if (currentStackFrame instanceof RootStackFrame) { + Span span = ((RootStackFrame) currentStackFrame).getSpan(); + span.setParentApplicationName(parentApplicationName); + span.setParentApplicationType(parentApplicationType); + logger.log(Level.FINE, "ParentApplicationName marked. parentApplicationName={}", parentApplicationName); + } else { + // do nothing. + } + } + + @Override + public void recordAcceptorHost(String host) { + StackFrame currentStackFrame = getCurrentStackFrame(); + if (currentStackFrame instanceof RootStackFrame) { + Span span = ((RootStackFrame) currentStackFrame).getSpan(); + span.setAcceptorHost(host); // me + logger.log(Level.FINE, "Acceptor host received. host={}", host); + } else { + // do nothing. + } + } + + @Override + public int getStackFrameId() { + return this.getCurrentStackFrame().getStackFrameId(); + + } +} \ No newline at end of file diff --git a/src/main/java/com/profiler/context/Trace.java b/src/main/java/com/profiler/context/Trace.java index 261596725..1aa2692f0 100644 --- a/src/main/java/com/profiler/context/Trace.java +++ b/src/main/java/com/profiler/context/Trace.java @@ -1,402 +1,82 @@ -package com.profiler.context; - -import com.profiler.common.AnnotationKey; -import com.profiler.common.ServiceType; -import com.profiler.common.util.ParsingResult; -import com.profiler.interceptor.MethodDescriptor; -import com.profiler.logging.LoggingUtils; -import com.profiler.util.StringUtils; - -import java.util.List; -import java.util.logging.Level; -import java.util.logging.Logger; - -/** - * @author netspider - */ -public final class Trace { - - private static final Logger logger = Logger.getLogger(Trace.class.getName()); - private static final boolean isDebug = LoggingUtils.isDebug(logger); - - public static final int NOCHECK_STACKID = -1; - public static final int ROOT_STACKID = 0; - - private short sequence; - - private boolean tracingEnabled = true; - - private CallStack callStack; - - private Storage storage; - - private TraceContext traceContext; - - // use for calculating depth of each Span. - private int latestStackIndex = -1; - - public Trace() { - TraceID traceId = TraceID.newTraceId(); - this.callStack = new CallStack(traceId); - latestStackIndex = this.callStack.push(); - StackFrame stackFrame = createRootStackFrame(ROOT_STACKID, callStack.getSpan()); - this.callStack.setStackFrame(stackFrame); - } - - public Trace(TraceID continueRoot) { - // this.root = continueRoot; - this.callStack = new CallStack(continueRoot); - latestStackIndex = this.callStack.push(); - StackFrame stackFrame = createRootStackFrame(ROOT_STACKID, callStack.getSpan()); - this.callStack.setStackFrame(stackFrame); - } - - public CallStack getCallStack() { - return callStack; - } - - - public Storage getStorage() { - return storage; - } - - public void setStorage(Storage storage) { - this.storage = storage; - } - - public short getSequence() { - return sequence++; - } - - public AsyncTrace createAsyncTrace() { - // 경우에 따라 별도 timeout 처리가 있어야 될수도 있음. - SpanEvent spanEvent = new SpanEvent(callStack.getSpan()); - spanEvent.setSequence(getSequence()); - AsyncTrace asyncTrace = new AsyncTrace(spanEvent); - // asyncTrace.setDataSender(this.getDataSender()); - asyncTrace.setStorage(this.storage); - return asyncTrace; - } - - private StackFrame createSubStackFrame(int stackId) { - SpanEvent spanEvent = new SpanEvent(callStack.getSpan()); - SubStackFrame stackFrame = new SubStackFrame(spanEvent); - stackFrame.setStackFrameId(stackId); - stackFrame.setSequence(getSequence()); - return stackFrame; - } - - private StackFrame createRootStackFrame(int stackId, Span span) { - RootStackFrame stackFrame = new RootStackFrame(span); - stackFrame.setStackFrameId(stackId); - stackFrame.setSpan(span); - stackFrame.setStackFrameId(ROOT_STACKID); - return stackFrame; - } - - public void traceBlockBegin() { - traceBlockBegin(NOCHECK_STACKID); - } - - public void markBeforeTime() { - StackFrame stackFrame = getCurrentStackFrame(); - stackFrame.markBeforeTime(); - } - - public long getBeforeTime() { - StackFrame stackFrame = getCurrentStackFrame(); - return stackFrame.getBeforeTime(); - } - - public void markAfterTime() { - StackFrame stackFrame = getCurrentStackFrame(); - stackFrame.markAfterTime(); - } - - public long getAfterTime() { - StackFrame stackFrame = getCurrentStackFrame(); - return stackFrame.getAfterTime(); - } - - - public void traceBlockBegin(int stackId) { - int currentStackIndex = callStack.push(); - StackFrame stackFrame = createSubStackFrame(stackId); - - if (latestStackIndex != currentStackIndex) { - latestStackIndex = currentStackIndex; - SpanEvent spanEvent = ((SubStackFrame) stackFrame).getSpanEvent(); - spanEvent.setDepth(latestStackIndex); - } - - callStack.setStackFrame(stackFrame); - } - - public void traceRootBlockEnd() { - traceBlockEnd(ROOT_STACKID); - } - - public void traceBlockEnd() { - traceBlockEnd(NOCHECK_STACKID); - } - - - public void traceBlockEnd(int stackId) { - StackFrame currentStackFrame = callStack.getCurrentStackFrame(); - int stackFrameId = currentStackFrame.getStackFrameId(); - if (stackFrameId != stackId) { - // 자체 stack dump를 하면 오류발견이 쉬울것으로 생각됨 - if (logger.isLoggable(Level.WARNING)) { - logger.warning("Corrupted CallStack found. StackId not matched. expected:" + stackId + " current:" + stackFrameId); - } - } - if (currentStackFrame instanceof RootStackFrame) { - logSpan(((RootStackFrame) currentStackFrame).getSpan()); - } else { - logSpan(((SubStackFrame) currentStackFrame).getSpanEvent()); - } - callStack.pop(); - } - - public StackFrame getCurrentStackFrame() { - return callStack.getCurrentStackFrame(); - } - - /** - * Get current TraceID. If it was not set this will return null. - * - * @return - */ - public TraceID getTraceId() { - return callStack.getSpan().getTraceID(); - } - - public void enable() { - tracingEnabled = true; - } - - public void disable() { - tracingEnabled = false; - } - - void logSpan(SpanEvent spanEvent) { - if (isDebug) { - Thread th = Thread.currentThread(); - logger.fine("[WRITE SpanEvent]" + spanEvent + ", Thread ID=" + th.getId() + " Name=" + th.getName()); - } - this.storage.store(spanEvent); - } - - void logSpan(Span span) { - if (isDebug) { - Thread th = Thread.currentThread(); - logger.info("[WRITE SPAN]" + span + ", Thread ID=" + th.getId() + " Name=" + th.getName()); - } - this.storage.store(span); - } - - public void recordException(Object result) { - if (result instanceof Throwable) { - Throwable th = (Throwable) result; - String drop = StringUtils.drop(th.getMessage(), 256); - recordAttribute(AnnotationKey.EXCEPTION, drop); - - Span span = getCallStack().getSpan(); - if (span.getException() == 0) { - span.setException(1); - } - } - } - - public void recordApi(MethodDescriptor methodDescriptor) { - if (methodDescriptor == null) { - return; - } - if (methodDescriptor.getApiId() == 0) { - recordAttribute(AnnotationKey.API, methodDescriptor.getFullName()); - } else { - recordAttribute(AnnotationKey.API_DID, methodDescriptor.getApiId()); - } - } - - public void recordApi(MethodDescriptor methodDescriptor, Object[] args) { - // API 저장 방법의 개선 필요. - recordApi(methodDescriptor); - recocordArgs(args); - } - - public void recordApi(int apiId) { - recordAttribute(AnnotationKey.API_ID, apiId); - } - - public void recordApi(int apiId, Object[] args) { - recordAttribute(AnnotationKey.API_ID, apiId); - recocordArgs(args); - } - - private void recocordArgs(Object[] args) { - if (args != null) { - int min = Math.min(args.length, AnnotationKey.MAX_ARGS_SIZE); - for (int i = 0; i < min; i++) { - recordAttribute(AnnotationKey.getArgs(i), args[i]); - } - // TODO MAX 사이즈를 넘는건 마크만 해줘야 하나? - } - } - - - public void recordAttribute(final AnnotationKey key, final String value) { - recordAttribute(key, (Object) value); - } - - public ParsingResult recordSqlInfo(String sql) { - if (sql == null) { - return null; - } - ParsingResult parsingResult = traceContext.parseSql(sql); - recordSqlParsingResult(parsingResult); - return parsingResult; - } - - public void recordSqlParsingResult(ParsingResult parsingResult) { - recordAttribute(AnnotationKey.SQL_ID, parsingResult.getSql().hashCode()); - String output = parsingResult.getOutput(); - if (output != null && output.length() != 0) { - recordAttribute(AnnotationKey.SQL_PARAM, output); - } - } - - public void recordAttribute(final AnnotationKey key, final Object value) { - // TODO API 단일화 필요. - StackFrame currentStackFrame = getCurrentStackFrame(); - if (currentStackFrame instanceof RootStackFrame) { - Span span = ((RootStackFrame) currentStackFrame).getSpan(); - span.addAnnotation(new Annotation(key, value)); - } else { - SpanEvent spanEvent = ((SubStackFrame) currentStackFrame).getSpanEvent(); - spanEvent.addAnnotation(new Annotation(key, value)); - } - - } - - - public void recordServiceType(final ServiceType serviceType) { - // TODO API 단일화 필요. - StackFrame currentStackFrame = getCurrentStackFrame(); - if (currentStackFrame instanceof RootStackFrame) { - Span span = ((RootStackFrame) currentStackFrame).getSpan(); - span.setServiceType(serviceType); - } else { - SpanEvent spanEvent = ((SubStackFrame) currentStackFrame).getSpanEvent(); - spanEvent.setServiceType(serviceType); - } - - } - - public void recordRpcName(final String rpc) { - // TODO API 단일화 필요. - StackFrame currentStackFrame = getCurrentStackFrame(); - if (currentStackFrame instanceof RootStackFrame) { - Span span = ((RootStackFrame) currentStackFrame).getSpan(); - span.setRpc(rpc); - } else { - SpanEvent spanEvent = ((SubStackFrame) currentStackFrame).getSpanEvent(); - spanEvent.setRpc(rpc); - } - - } - - public void recordDestinationId(final String destinationId) { - // TODO API 단일화 필요. - StackFrame currentStackFrame = getCurrentStackFrame(); - if (currentStackFrame instanceof SubStackFrame) { - SpanEvent spanEvent = ((SubStackFrame) currentStackFrame).getSpanEvent(); - spanEvent.setDestionationId(destinationId); - } - } - - public void recordDestinationAddress(List address) { - // TODO API 단일화 필요. - StackFrame currentStackFrame = getCurrentStackFrame(); - if (currentStackFrame instanceof SubStackFrame) { - SpanEvent spanEvent = ((SubStackFrame) currentStackFrame).getSpanEvent(); - spanEvent.setDestinationAddress(); - } - } - - public void recordDestinationAddressList(List addressList) { - //To change body of created methods use File | Settings | File Templates. - } - - public void recordEndPoint(final String endPoint) { - // TODO API 단일화 필요. - StackFrame currentStackFrame = getCurrentStackFrame(); - if (currentStackFrame instanceof RootStackFrame) { - Span span = ((RootStackFrame) currentStackFrame).getSpan(); - span.setEndPoint(endPoint); - } else { - SpanEvent spanEvent = ((SubStackFrame) currentStackFrame).getSpanEvent(); - spanEvent.setEndPoint(endPoint); - } - } - - public void recordRemoteAddr(final String remoteAddr) { - // TODO API 단일화 필요. - StackFrame currentStackFrame = getCurrentStackFrame(); - if (currentStackFrame instanceof RootStackFrame) { - Span span = ((RootStackFrame) currentStackFrame).getSpan(); - span.setRemoteAddr(remoteAddr); - } else { - // do nothing. - } - } - - public void recordNextSpanId(int spanId) { - StackFrame currentStackFrame = getCurrentStackFrame(); - if (currentStackFrame instanceof RootStackFrame) { - logger.log(Level.WARNING, "OMG. Something's going wrong. Current stackframe is root Span. nextSpanId={}", spanId); - } else { - SpanEvent spanEvent = ((SubStackFrame) currentStackFrame).getSpanEvent(); - spanEvent.setNextSpanId(spanId); - } - } - - private void annotate(final AnnotationKey key) { - StackFrame currentStackFrame = getCurrentStackFrame(); - if (currentStackFrame instanceof RootStackFrame) { - Span span = ((RootStackFrame) currentStackFrame).getSpan(); - span.addAnnotation(new Annotation(key)); - } else { - SpanEvent spanEvent = ((SubStackFrame) currentStackFrame).getSpanEvent(); - spanEvent.addAnnotation(new Annotation(key)); - } - - } - - public void setTraceContext(TraceContext traceContext) { - this.traceContext = traceContext; - } - - public void recordParentApplication(String parentApplicationName, short parentApplicationType) { - StackFrame currentStackFrame = getCurrentStackFrame(); - if (currentStackFrame instanceof RootStackFrame) { - Span span = ((RootStackFrame) currentStackFrame).getSpan(); - span.setParentApplicationName(parentApplicationName); - span.setParentApplicationType(parentApplicationType); - logger.log(Level.FINE, "ParentApplicationName marked. parentApplicationName={}", parentApplicationName); - } else { - // do nothing. - } - } - - public void recordAcceptorHost(String host) { - StackFrame currentStackFrame = getCurrentStackFrame(); - if (currentStackFrame instanceof RootStackFrame) { - Span span = ((RootStackFrame) currentStackFrame).getSpan(); - span.setAcceptorHost(host); // me - logger.log(Level.FINE, "Acceptor host received. host={}", host); - } else { - // do nothing. - } - } -} \ No newline at end of file +package com.profiler.context; + +import com.profiler.common.AnnotationKey; +import com.profiler.common.ServiceType; +import com.profiler.common.util.ParsingResult; +import com.profiler.interceptor.MethodDescriptor; + +import java.util.List; + +/** + * + */ +public interface Trace { + + AsyncTrace createAsyncTrace(); + + void traceBlockBegin(); + + void markBeforeTime(); + + long getBeforeTime(); + + void markAfterTime(); + + long getAfterTime(); + + void traceBlockBegin(int stackId); + + void traceRootBlockEnd(); + + void traceBlockEnd(); + + void traceBlockEnd(int stackId); + + TraceID getTraceId(); + + void enable(); + + void disable(); + + void recordException(Object result); + + void recordApi(MethodDescriptor methodDescriptor); + + void recordApi(MethodDescriptor methodDescriptor, Object[] args); + + void recordApi(int apiId); + + void recordApi(int apiId, Object[] args); + + void recordAttribute(AnnotationKey key, String value); + + ParsingResult recordSqlInfo(String sql); + + void recordSqlParsingResult(ParsingResult parsingResult); + + void recordAttribute(AnnotationKey key, Object value); + + void recordServiceType(ServiceType serviceType); + + void recordRpcName(String rpc); + + void recordDestinationId(String destinationId); + + void recordDestinationAddress(List address); + + void recordDestinationAddressList(List addressList); + + void recordEndPoint(String endPoint); + + void recordRemoteAddr(String remoteAddr); + + void recordNextSpanId(int spanId); + + void setTraceContext(TraceContext traceContext); + + void recordParentApplication(String parentApplicationName, short parentApplicationType); + + void recordAcceptorHost(String host); + + int getStackFrameId(); +} diff --git a/src/main/java/com/profiler/context/TraceContext.java b/src/main/java/com/profiler/context/TraceContext.java index 43ff1e3ab..5e8837b4d 100644 --- a/src/main/java/com/profiler/context/TraceContext.java +++ b/src/main/java/com/profiler/context/TraceContext.java @@ -63,7 +63,7 @@ public class TraceContext { return threadLocal.get(); } - public void attachTraceObject(Trace trace) { + public void attachTraceObject(DefaultTrace trace) { Trace old = this.threadLocal.get(); if (old != null) { // 잘못된 상황의 old를 덤프할것. diff --git a/src/main/java/com/profiler/modifier/bloc/handler/interceptors/ExecuteMethodInterceptor.java b/src/main/java/com/profiler/modifier/bloc/handler/interceptors/ExecuteMethodInterceptor.java index 9878e1aa7..58cd8c9b1 100644 --- a/src/main/java/com/profiler/modifier/bloc/handler/interceptors/ExecuteMethodInterceptor.java +++ b/src/main/java/com/profiler/modifier/bloc/handler/interceptors/ExecuteMethodInterceptor.java @@ -7,11 +7,7 @@ import java.util.logging.Logger; import com.profiler.common.AnnotationKey; import com.profiler.common.ServiceType; -import com.profiler.context.Header; -import com.profiler.context.SpanID; -import com.profiler.context.Trace; -import com.profiler.context.TraceContext; -import com.profiler.context.TraceID; +import com.profiler.context.*; import com.profiler.interceptor.ByteCodeMethodDescriptorSupport; import com.profiler.interceptor.MethodDescriptor; import com.profiler.interceptor.StaticAroundInterceptor; @@ -45,7 +41,7 @@ public class ExecuteMethodInterceptor implements StaticAroundInterceptor, ByteCo String parameters = getRequestParameter(request); TraceID traceId = populateTraceIdFromRequest(request); - Trace trace; + DefaultTrace trace; if (traceId != null) { // TraceID nextTraceId = traceId.getNextTraceId(); if (logger.isLoggable(Level.INFO)) { @@ -54,10 +50,10 @@ public class ExecuteMethodInterceptor implements StaticAroundInterceptor, ByteCo logger.log(Level.FINE, "requestUrl:" + requestURL + " clientIp" + clientIP + " parameter:" + parameters); } // trace = new Trace(nextTraceId); - trace = new Trace(traceId); + trace = new DefaultTrace(traceId); traceContext.attachTraceObject(trace); } else { - trace = new Trace(); + trace = new DefaultTrace(); if (logger.isLoggable(Level.INFO)) { logger.info("TraceID not exist. start new trace. " + trace.getTraceId()); logger.log(Level.FINE, "requestUrl:" + requestURL + " clientIp" + clientIP + " parameter:" + parameters); @@ -98,7 +94,7 @@ public class ExecuteMethodInterceptor implements StaticAroundInterceptor, ByteCo return; } traceContext.detachTraceObject(); - if (trace.getCurrentStackFrame().getStackFrameId() != 0) { + if (trace.getStackFrameId() != 0) { logger.warning("Corrupted CallStack found. StackId not Root(0)"); // 문제 있는 callstack을 dump하면 도움이 될듯. } diff --git a/src/main/java/com/profiler/modifier/servlet/interceptors/DoXXXInterceptor.java b/src/main/java/com/profiler/modifier/servlet/interceptors/DoXXXInterceptor.java index 3fa63864a..e187ba5f9 100644 --- a/src/main/java/com/profiler/modifier/servlet/interceptors/DoXXXInterceptor.java +++ b/src/main/java/com/profiler/modifier/servlet/interceptors/DoXXXInterceptor.java @@ -9,11 +9,7 @@ import javax.servlet.http.HttpServletRequest; import com.profiler.common.AnnotationKey; import com.profiler.common.ServiceType; -import com.profiler.context.Header; -import com.profiler.context.SpanID; -import com.profiler.context.Trace; -import com.profiler.context.TraceContext; -import com.profiler.context.TraceID; +import com.profiler.context.*; import com.profiler.interceptor.ByteCodeMethodDescriptorSupport; import com.profiler.interceptor.MethodDescriptor; import com.profiler.interceptor.StaticAroundInterceptor; @@ -67,7 +63,7 @@ public class DoXXXInterceptor implements StaticAroundInterceptor, ByteCodeMethod String clientIP = request.getRemoteAddr(); TraceID traceId = populateTraceIdFromRequest(request); - Trace trace; + DefaultTrace trace; if (traceId != null) { // TraceID nextTraceId = traceId.getNextTraceId(); if (logger.isLoggable(Level.INFO)) { @@ -76,10 +72,10 @@ public class DoXXXInterceptor implements StaticAroundInterceptor, ByteCodeMethod logger.log(Level.FINE, "requestUrl:" + requestURL + " clientIp" + clientIP); } // trace = new Trace(nextTraceId); - trace = new Trace(traceId); + trace = new DefaultTrace(traceId); traceContext.attachTraceObject(trace); } else { - trace = new Trace(); + trace = new DefaultTrace(); if (logger.isLoggable(Level.INFO)) { logger.info("TraceID not exist. start new trace. " + trace.getTraceId()); logger.log(Level.FINE, "requestUrl:" + requestURL + " clientIp" + clientIP); @@ -122,7 +118,7 @@ public class DoXXXInterceptor implements StaticAroundInterceptor, ByteCodeMethod } - if (trace.getCurrentStackFrame().getStackFrameId() != 0) { + if (trace.getStackFrameId() != 0) { logger.warning("Corrupted CallStack found. StackId not Root(0)"); // 문제 있는 callstack을 dump하면 도움이 될듯. } diff --git a/src/main/java/com/profiler/modifier/tomcat/interceptors/StandardHostValveInvokeInterceptor.java b/src/main/java/com/profiler/modifier/tomcat/interceptors/StandardHostValveInvokeInterceptor.java index bad6884ab..4cbb6351c 100644 --- a/src/main/java/com/profiler/modifier/tomcat/interceptors/StandardHostValveInvokeInterceptor.java +++ b/src/main/java/com/profiler/modifier/tomcat/interceptors/StandardHostValveInvokeInterceptor.java @@ -9,11 +9,7 @@ import javax.servlet.http.HttpServletRequest; import com.profiler.common.AnnotationKey; import com.profiler.common.ServiceType; -import com.profiler.context.Header; -import com.profiler.context.SpanID; -import com.profiler.context.Trace; -import com.profiler.context.TraceContext; -import com.profiler.context.TraceID; +import com.profiler.context.*; import com.profiler.interceptor.ByteCodeMethodDescriptorSupport; import com.profiler.interceptor.MethodDescriptor; import com.profiler.interceptor.StaticAroundInterceptor; @@ -45,17 +41,17 @@ public class StandardHostValveInvokeInterceptor implements StaticAroundIntercept String remoteAddr = request.getRemoteAddr(); TraceID traceId = populateTraceIdFromRequest(request); - Trace trace; + DefaultTrace trace; if (traceId != null) { if (logger.isLoggable(Level.INFO)) { logger.info("TraceID exist. continue trace. " + traceId); logger.log(Level.FINE, "requestUrl:" + requestURL + ", remoteAddr:" + remoteAddr); } // trace = new Trace(nextTraceId); - trace = new Trace(traceId); + trace = new DefaultTrace(traceId); traceContext.attachTraceObject(trace); } else { - trace = new Trace(); + trace = new DefaultTrace(); if (logger.isLoggable(Level.INFO)) { logger.info("TraceID not exist. start new trace. " + trace.getTraceId()); logger.log(Level.FINE, "requestUrl:" + requestURL + ", remoteAddr:" + remoteAddr); @@ -110,7 +106,7 @@ public class StandardHostValveInvokeInterceptor implements StaticAroundIntercept } - if (trace.getCurrentStackFrame().getStackFrameId() != 0) { + if (trace.getStackFrameId() != 0) { logger.warning("Corrupted CallStack found. StackId not Root(0)"); // 문제 있는 callstack을 dump하면 도움이 될듯. }