mirror of
https://github.com/wahyd4/pinpoint.git
synced 2026-08-20 18:25:55 +10:00
[강운덕] [LUCYSUS-1744] 클래스 로더 분리를 위해서 Trace를 인터페이스로 분리.
git-svn-id: http://svn.bds.nhncorp.com/pe/hippo-tomcat-profiler/trunk@1359 84d0f5b1-2673-498c-a247-62c4ff18d310
This commit is contained in:
@@ -51,6 +51,14 @@ public class TomcatProfiler implements ClassFileTransformer {
|
||||
}
|
||||
// 이게 로드할 lib List임.
|
||||
List<URL> 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);
|
||||
|
||||
@@ -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<String> address) {
|
||||
// TODO API 단일화 필요.
|
||||
StackFrame currentStackFrame = getCurrentStackFrame();
|
||||
if (currentStackFrame instanceof SubStackFrame) {
|
||||
SpanEvent spanEvent = ((SubStackFrame) currentStackFrame).getSpanEvent();
|
||||
spanEvent.setDestinationAddress();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void recordDestinationAddressList(List<String> 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();
|
||||
|
||||
}
|
||||
}
|
||||
@@ -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<String> address) {
|
||||
// TODO API 단일화 필요.
|
||||
StackFrame currentStackFrame = getCurrentStackFrame();
|
||||
if (currentStackFrame instanceof SubStackFrame) {
|
||||
SpanEvent spanEvent = ((SubStackFrame) currentStackFrame).getSpanEvent();
|
||||
spanEvent.setDestinationAddress();
|
||||
}
|
||||
}
|
||||
|
||||
public void recordDestinationAddressList(List<String> 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.
|
||||
}
|
||||
}
|
||||
}
|
||||
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<String> address);
|
||||
|
||||
void recordDestinationAddressList(List<String> 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();
|
||||
}
|
||||
|
||||
@@ -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를 덤프할것.
|
||||
|
||||
+5
-9
@@ -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하면 도움이 될듯.
|
||||
}
|
||||
|
||||
@@ -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하면 도움이 될듯.
|
||||
}
|
||||
|
||||
+5
-9
@@ -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하면 도움이 될듯.
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user