[유치수] [NOBTS] call stack을 위한 수정, depth, nextid 추가. traceid를 rpc call하기 전에 next id를 발급하도록 변경.

git-svn-id: http://svn.bds.nhncorp.com/pe/hippo-tomcat-profiler/trunk@1113 84d0f5b1-2673-498c-a247-62c4ff18d310
This commit is contained in:
Chisu Yu
2013-01-24 04:53:17 +00:00
parent 09fb7f49a7
commit 750352c96f
13 changed files with 333 additions and 197 deletions
+184 -170
View File
@@ -13,7 +13,6 @@ import com.profiler.interceptor.MethodDescriptor;
import com.profiler.metadata.SqlCacheTable;
import com.profiler.sender.DataSender;
import com.profiler.sender.LoggingDataSender;
import com.profiler.util.Assert;
/**
* @author netspider
@@ -24,7 +23,6 @@ public final class Trace {
private static final DataSender DEFULT_DATA_SENDER = new LoggingDataSender();
public static final int HANDLER_STACKID = -2;
public static final int NOCHECK_STACKID = -1;
public static final int ROOT_STACKID = 0;
@@ -40,22 +38,25 @@ public final class Trace {
private SqlCacheTable sqlCacheTable;
private SqlParser sqlParser;
// use for calculating depth of each Span.
private Integer latestStackIndex = null;
public Trace() {
// traceObject에서 spanid의 유효성을 히스토리를 관리한다면 같은 thread에서는 span랜덤생성아이디의 충돌을 방지할수 있기는 함.
TraceID traceId = TraceID.newTraceId();
this.callStack = new CallStack(traceId);
this.callStack.push();
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);
this.callStack.push();
// StackFrame stackFrame = createStackFrame(ROOT_STACKID);
StackFrame stackFrame = createRootStackFrame(ROOT_STACKID, callStack.getSpan());
this.callStack.setStackFrame(stackFrame);
// this.root = continueRoot;
this.callStack = new CallStack(continueRoot);
latestStackIndex = this.callStack.push();
// StackFrame stackFrame = createStackFrame(ROOT_STACKID);
StackFrame stackFrame = createRootStackFrame(ROOT_STACKID, callStack.getSpan());
this.callStack.setStackFrame(stackFrame);
}
public CallStack getCallStack() {
@@ -80,13 +81,13 @@ public final class Trace {
}
public AsyncTrace createAsyncTrace() {
// 경우에 따라 별도 timeout 처리가 있어야 될수도 있음.
SubSpan subSpan = new SubSpan(callStack.getSpan());
subSpan.setSequence(getSequence());
AsyncTrace asyncTrace = new AsyncTrace(subSpan);
// asyncTrace.setDataSender(this.getDataSender());
asyncTrace.setStorage(this.storage);
return asyncTrace;
// 경우에 따라 별도 timeout 처리가 있어야 될수도 있음.
SubSpan subSpan = new SubSpan(callStack.getSpan());
subSpan.setSequence(getSequence());
AsyncTrace asyncTrace = new AsyncTrace(subSpan);
// asyncTrace.setDataSender(this.getDataSender());
asyncTrace.setStorage(this.storage);
return asyncTrace;
}
private StackFrame createSubStackFrame(int stackId) {
@@ -103,19 +104,18 @@ public final class Trace {
stackFrame.setSpan(span);
stackFrame.setStackFrameId(ROOT_STACKID);
return stackFrame;
}
}
public void traceBlockBegin() {
traceBlockBegin(NOCHECK_STACKID);
}
public void traceBlockBegin() {
traceBlockBegin(NOCHECK_STACKID);
}
public void markBeforeTime() {
StackFrame stackFrame = getCurrentStackFrame();
stackFrame.markBeforeTime();
}
public void markBeforeTime() {
StackFrame stackFrame = getCurrentStackFrame();
stackFrame.markBeforeTime();
}
public long getBeforeTime() {
public long getBeforeTime() {
StackFrame stackFrame = getCurrentStackFrame();
return stackFrame.getBeforeTime();
}
@@ -135,13 +135,18 @@ public final class Trace {
// stackFrame.attachObject(object);
// }
public void traceBlockBegin(int stackId) {
int currentStackIndex = callStack.push();
StackFrame stackFrame = createSubStackFrame(stackId);
if (latestStackIndex != currentStackIndex) {
latestStackIndex = currentStackIndex;
SubSpan span = ((SubStackFrame) stackFrame).getSubSpan();
span.setDepth(latestStackIndex);
}
public void traceBlockBegin(int stackId) {
// TraceID nextId = getNextTraceId();
callStack.push();
StackFrame stackFrame = createSubStackFrame(stackId);
callStack.setStackFrame(stackFrame);
}
callStack.setStackFrame(stackFrame);
}
public void traceBlockEnd() {
traceBlockEnd(NOCHECK_STACKID);
@@ -170,7 +175,6 @@ public final class Trace {
callStack.pop();
}
public StackFrame getCurrentStackFrame() {
return callStack.getCurrentStackFrame();
}
@@ -214,10 +218,10 @@ public final class Trace {
logger.info("[WRITE SPAN]" + span + " CurrentThreadID=" + Thread.currentThread().getId() + ",\n\t CurrentThreadName=" + Thread.currentThread().getName() + "\n\n");
}
// dataSender.send(span);
this.storage.store(span);
// subSpan.cancelTimer();
} catch (Exception e) {
// dataSender.send(span);
this.storage.store(span);
// subSpan.cancelTimer();
} catch (Exception e) {
logger.log(Level.SEVERE, e.getMessage(), e);
}
}
@@ -230,80 +234,78 @@ public final class Trace {
annotate(annotation.getCode());
}
public void recordException(Object result) {
if (result instanceof Throwable) {
Throwable th = (Throwable) result;
recordAttribute(AnnotationNames.EXCEPTION, th.getMessage());
public void recordException(Object result) {
if (result instanceof Throwable) {
Throwable th = (Throwable) result;
recordAttribute(AnnotationNames.EXCEPTION, th.getMessage());
try {
StackFrame currentStackFrame = getCurrentStackFrame();
if (currentStackFrame instanceof RootStackFrame) {
((RootStackFrame) currentStackFrame).getSpan().setException(true);
} else {
((SubStackFrame) currentStackFrame).getSubSpan().setException(true);
}
} catch (Exception e) {
logger.log(Level.SEVERE, e.getMessage(), e);
}
}
}
try {
StackFrame currentStackFrame = getCurrentStackFrame();
if (currentStackFrame instanceof RootStackFrame) {
((RootStackFrame) currentStackFrame).getSpan().setException(true);
} else {
((SubStackFrame) currentStackFrame).getSubSpan().setException(true);
}
} catch (Exception e) {
logger.log(Level.SEVERE, e.getMessage(), e);
}
}
}
public void recordApi(MethodDescriptor methodDescriptor) {
if (methodDescriptor == null) {
return;
}
String method = methodDescriptor.getClassName() + "." + methodDescriptor.getMethodName() + methodDescriptor.getParameterDescriptor() + ":" + methodDescriptor.getLineNumber();
recordAttribute(AnnotationNames.API, method);
}
public void recordApi(MethodDescriptor methodDescriptor) {
if (methodDescriptor == null) {
return;
}
String method = methodDescriptor.getClassName() + "." + methodDescriptor.getMethodName() + methodDescriptor.getParameterDescriptor() + ":" + methodDescriptor.getLineNumber();
recordAttribute(AnnotationNames.API, method);
}
public void recordApi(MethodDescriptor methodDescriptor, Object[] args) {
// API 저장 방법의 개선 필요.
String method = methodDescriptor.getClassName() + "." + methodDescriptor.getMethodName() + methodDescriptor.getParameterDescriptor() + ":" + methodDescriptor.getLineNumber();
recordAttribute(AnnotationNames.API, method);
recocordArgs(args);
}
public void recordApi(MethodDescriptor methodDescriptor, Object[] args) {
// API 저장 방법의 개선 필요.
String method = methodDescriptor.getClassName() + "." + methodDescriptor.getMethodName() + methodDescriptor.getParameterDescriptor() + ":" + methodDescriptor.getLineNumber();
recordAttribute(AnnotationNames.API, method);
recocordArgs(args);
}
public void recordApi(int apiId) {
recordAttribute(AnnotationNames.API_ID, apiId);
}
public void recordApi(int apiId) {
recordAttribute(AnnotationNames.API_ID, apiId);
}
public void recordApi(int apiId, Object[] args) {
recordAttribute(AnnotationNames.API_ID, apiId);
recocordArgs(args);
}
public void recordApi(int apiId, Object[] args) {
recordAttribute(AnnotationNames.API_ID, apiId);
recocordArgs(args);
}
private void recocordArgs(Object[] args) {
if (args != null) {
for (int i = 0; i < args.length; i++) {
recordAttribute("args[" + i + "]", args[i]);
}
}
}
private void recocordArgs(Object[] args) {
if (args != null) {
for (int i = 0; i < args.length; i++) {
recordAttribute("args[" + i + "]", args[i]);
}
}
}
public void recordAttribute(final String key, final String value) {
recordAttribute(key, (Object) value);
}
public void recordAttribute(final String key, final String value) {
recordAttribute(key, (Object) value);
}
public ParsingResult recordSqlInfo(String sql) {
if (sql == null) {
return null;
}
ParsingResult parsingResult = parseSql(sql);
recordSqlParsingResult(parsingResult);
return parsingResult;
}
public ParsingResult recordSqlInfo(String sql) {
if (sql == null) {
return null;
}
ParsingResult parsingResult = parseSql(sql);
recordSqlParsingResult(parsingResult);
return parsingResult;
}
public void recordSqlParsingResult(ParsingResult parsingResult) {
recordAttribute(AnnotationNames.SQL_ID, parsingResult.getSql().hashCode());
String output = parsingResult.getOutput();
if (output != null && output.length() != 0) {
recordAttribute(AnnotationNames.SQL_PARAM, output);
}
}
public ParsingResult parseSql(String sql) {
public void recordSqlParsingResult(ParsingResult parsingResult) {
recordAttribute(AnnotationNames.SQL_ID, parsingResult.getSql().hashCode());
String output = parsingResult.getOutput();
if (output != null && output.length() != 0) {
recordAttribute(AnnotationNames.SQL_PARAM, output);
}
}
public ParsingResult parseSql(String sql) {
// 해당 api의 구현을 그냥 tarceContext api에 만들어야 될듯 하다.
ParsingResult parsingResult = this.sqlParser.normalizedSql(sql);
String normalizedSql = parsingResult.getSql();
@@ -330,56 +332,55 @@ public final class Trace {
return parsingResult;
}
public void recordAttribute(final String key, final Object value) {
if (!tracingEnabled)
return;
public void recordAttribute(final String key, final Object value) {
if (!tracingEnabled)
return;
try {
// TODO API 단일화 필요.
StackFrame currentStackFrame = getCurrentStackFrame();
if (currentStackFrame instanceof RootStackFrame) {
Span span = ((RootStackFrame) currentStackFrame).getSpan();
span.addAnnotation(new HippoAnnotation(key, value));
} else {
SubSpan span = ((SubStackFrame) currentStackFrame).getSubSpan();
span.addAnnotation(new HippoAnnotation(key, value));
}
} catch (Exception e) {
logger.log(Level.SEVERE, e.getMessage(), e);
}
}
try {
// TODO API 단일화 필요.
StackFrame currentStackFrame = getCurrentStackFrame();
if (currentStackFrame instanceof RootStackFrame) {
Span span = ((RootStackFrame) currentStackFrame).getSpan();
span.addAnnotation(new HippoAnnotation(key, value));
} else {
SubSpan span = ((SubStackFrame) currentStackFrame).getSubSpan();
span.addAnnotation(new HippoAnnotation(key, value));
}
} catch (Exception e) {
logger.log(Level.SEVERE, e.getMessage(), e);
}
}
public void recordMessage(String message) {
if (!tracingEnabled)
return;
public void recordMessage(String message) {
if (!tracingEnabled)
return;
annotate(message);
}
annotate(message);
}
public void recordRpcName(final ServiceType serviceType, final String serviceName, final String rpc) {
if (!tracingEnabled)
return;
public void recordRpcName(final ServiceType serviceType, final String serviceName, final String rpc) {
if (!tracingEnabled)
return;
try {
// TODO API 단일화 필요.
StackFrame currentStackFrame = getCurrentStackFrame();
if (currentStackFrame instanceof RootStackFrame) {
Span span = ((RootStackFrame) currentStackFrame).getSpan();
span.setServiceType(serviceType);
span.setServiceName(serviceName);
span.setRpc(rpc);
} else {
SubSpan span = ((SubStackFrame) currentStackFrame).getSubSpan();
span.setServiceType(serviceType);
span.setServiceName(serviceName);
span.setRpc(rpc);
}
} catch (Exception e) {
logger.log(Level.SEVERE, e.getMessage(), e);
}
}
try {
// TODO API 단일화 필요.
StackFrame currentStackFrame = getCurrentStackFrame();
if (currentStackFrame instanceof RootStackFrame) {
Span span = ((RootStackFrame) currentStackFrame).getSpan();
span.setServiceType(serviceType);
span.setServiceName(serviceName);
span.setRpc(rpc);
} else {
SubSpan span = ((SubStackFrame) currentStackFrame).getSubSpan();
span.setServiceType(serviceType);
span.setServiceName(serviceName);
span.setRpc(rpc);
}
} catch (Exception e) {
logger.log(Level.SEVERE, e.getMessage(), e);
}
}
// TODO: final String... endPoint로 받으면 합치는데 비용이 들어가 그냥 한번에 받는게 나을것 같음.
public void recordEndPoint(final String endPoint) {
if (!tracingEnabled)
return;
@@ -396,35 +397,48 @@ public final class Trace {
} catch (Exception e) {
logger.log(Level.SEVERE, e.getMessage(), e);
}
}
}
private void annotate(final String key) {
if (!tracingEnabled)
return;
public void recordNextSpanId(long spanId) {
if (!tracingEnabled)
return;
try {
StackFrame currentStackFrame = getCurrentStackFrame();
if (currentStackFrame instanceof RootStackFrame) {
Span span = ((RootStackFrame) currentStackFrame).getSpan();
span.addAnnotation(new HippoAnnotation(key));
} else {
SubSpan span = ((SubStackFrame) currentStackFrame).getSubSpan();
span.addAnnotation(new HippoAnnotation(key));
}
try {
StackFrame currentStackFrame = getCurrentStackFrame();
if (currentStackFrame instanceof RootStackFrame) {
logger.log(Level.WARNING, "OMG. Something's going wrong. Current stackframe is root Span. nextSpanId={}", spanId);
} else {
SubSpan span = ((SubStackFrame) currentStackFrame).getSubSpan();
span.setNextSpanId(spanId);
}
} catch (Exception e) {
logger.log(Level.SEVERE, e.getMessage(), e);
}
}
} catch (Exception e) {
logger.log(Level.SEVERE, e.getMessage(), e);
}
}
private void annotate(final String key) {
if (!tracingEnabled)
return;
try {
StackFrame currentStackFrame = getCurrentStackFrame();
if (currentStackFrame instanceof RootStackFrame) {
Span span = ((RootStackFrame) currentStackFrame).getSpan();
span.addAnnotation(new HippoAnnotation(key));
} else {
SubSpan span = ((SubStackFrame) currentStackFrame).getSubSpan();
span.addAnnotation(new HippoAnnotation(key));
}
} catch (Exception e) {
logger.log(Level.SEVERE, e.getMessage(), e);
}
}
public void setSqlCacheTable(SqlCacheTable sqlCacheTable) {
this.sqlCacheTable = sqlCacheTable;
}
public void setSqlParser(SqlParser sqlParser) {
this.sqlParser = sqlParser;
}
public void setSqlCacheTable(SqlCacheTable sqlCacheTable) {
this.sqlCacheTable = sqlCacheTable;
}
public void setSqlParser(SqlParser sqlParser) {
this.sqlParser = sqlParser;
}
}