[유치수] [NOBTS] refactor

git-svn-id: http://svn.bds.nhncorp.com/pe/hippo-tomcat-profiler/trunk@580 84d0f5b1-2673-498c-a247-62c4ff18d310
This commit is contained in:
Chisu Yu
2012-09-05 06:06:25 +00:00
parent ac01a697db
commit c4008035e8
11 changed files with 127 additions and 80 deletions
+20 -8
View File
@@ -9,25 +9,37 @@ public class StopWatch {
private static ThreadLocal<Map<String, Long>> local = new NamedThreadLocal<Map<String, Long>>("StopWatch");
public static void start(String name) {
public static void start(int id) {
start(String.valueOf(id));
}
public static long stopAndGetElapsed(int id) {
return stopAndGetElapsed(String.valueOf(id));
}
public static void start(String id) {
Map<String, Long> map = local.get();
if (map == null) {
map = new HashMap<String, Long>(1);
map.put(name, System.nanoTime());
map.put(id, System.nanoTime());
local.set(map);
} else {
map.put(name, System.nanoTime());
map.put(id, System.nanoTime());
}
}
public static long stopAndGetElapsed(String name) {
public static long stopAndGetElapsed(String id) {
Map<String, Long> map = local.get();
if (map == null) {
//throw new IllegalStateException("Stopwatch is not started.");
// TODO application 에러로 전달되는경우가 있어서 일단 0으로
return 0;
// throw new IllegalStateException("Stopwatch is not started.");
// TODO application 에러로 전달되는경우가 있어서 일단 0으로
return -1;
} else {
return System.nanoTime() - map.get(name);
if (map.containsKey(id)) {
return System.nanoTime() - map.get(id);
} else {
return -1;
}
}
}
}
@@ -7,6 +7,12 @@ public class HippoAnnotation {
protected final Long duration;
protected final String threadname; // TODO: remove, just for debug.
/**
*
* @param time
* @param value
* @param duration duration in nano second.
*/
public HippoAnnotation(long time, String value, Long duration) {
this.time = time;
this.value = value;
+9 -5
View File
@@ -24,16 +24,20 @@ public class Span {
private final List<HippoAnnotation> annotations = new ArrayList<HippoAnnotation>(5);
private final Set<String> annotationValues = new HashSet<String>(5);
/**
* Cancel timer logic.
* TODO: refactor this.
*/
private TimerTask timerTask;
public void setTimerTask(TimerTask task) {
this.timerTask = task;
}
public boolean cancelTimer() {
return timerTask.cancel();
}
public Span(TraceID traceId, String name, EndPoint endPoint) {
this.traceID = traceId;
this.name = name;
@@ -108,8 +112,8 @@ public class Span {
com.profiler.context.gen.Span span = new com.profiler.context.gen.Span();
span.setTimestamp(createTime);
span.setMostTraceID(traceID.getTraceId().getMostSignificantBits());
span.setLeastTraceID(traceID.getTraceId().getLeastSignificantBits());
span.setMostTraceID(traceID.getId().getMostSignificantBits());
span.setLeastTraceID(traceID.getId().getLeastSignificantBits());
span.setName(name);
span.setSpanID(traceID.getSpanId());
span.setParentSpanId(traceID.getParentSpanId());
+30 -18
View File
@@ -17,7 +17,7 @@ public final class Trace {
private static final DeadlineSpanMap spanMap = new DeadlineSpanMap();
private static final ThreadLocal<TraceID> traceId = new NamedThreadLocal<TraceID>("TraceId");
private static final ThreadLocal<TraceID> traceIdLocal = new NamedThreadLocal<TraceID>("TraceId");
private static volatile boolean tracingEnabled = true;
@@ -30,12 +30,12 @@ public final class Trace {
*
* @return
*/
public static TraceID getTraceId() {
TraceID id = traceId.get();
public static TraceID getTraceIdOrCreateNew() {
TraceID id = traceIdLocal.get();
if (id == null) {
id = TraceID.newTraceId();
traceId.set(id);
traceIdLocal.set(id);
return id;
}
@@ -43,9 +43,10 @@ public final class Trace {
}
public static boolean removeTraceId() {
TraceID traceID = traceId.get();
TraceID traceID = traceIdLocal.get();
if (traceID != null) {
traceId.remove();
traceIdLocal.remove();
spanMap.remove(traceID);
return true;
}
return false;
@@ -57,7 +58,7 @@ public final class Trace {
* @return
*/
public static TraceID getCurrentTraceId() {
return traceId.get();
return traceIdLocal.get();
}
public static void enable() {
@@ -68,13 +69,16 @@ public final class Trace {
tracingEnabled = false;
}
public static TraceID getNextId() {
TraceID current = getTraceId();
return new TraceID(current.getTraceId(), current.getSpanId(), SpanID.newSpanID(), current.isSampled(), current.getFlags());
public static TraceID getNextTraceId() {
TraceID current = getTraceIdOrCreateNew();
return new TraceID(current.getId(), current.getSpanId(), SpanID.newSpanID(), current.isSampled(), current.getFlags());
}
public static void setTraceId(TraceID traceId) {
Trace.traceId.set(traceId);
if (getCurrentTraceId() != null) {
logger.log(Level.WARNING, "TraceID is already exists. But overwritten.");
}
Trace.traceIdLocal.set(traceId);
}
private static void mutate(TraceID traceId, SpanUpdater spanUpdater) {
@@ -88,9 +92,16 @@ public final class Trace {
static void logSpan(Span span) {
try {
// TODO: send span to server
System.out.println("\n\nWrite span hash=" + span.hashCode() + ", value=" + span + ", spanMap.size=" + spanMap.size() + ", threadid=" + Thread.currentThread().getId() + "\n\n");
// TODO: send span to the server.
System.out.println("\n\n[WRITE SPAN] hashCode=" + span.hashCode() + ", Value=" + span + ", SpanMap.size=" + spanMap.size() + ", CurrentThreadID=" + Thread.currentThread().getId() + "\n\n");
// TODO: remove this, just for debugging
if(spanMap.size() > 0) {
System.out.println("###############################################################");
System.out.println("# WARNING SpanMap size > 0 check spanMap. #");
System.out.println("###############################################################");
}
DataSender.getInstance().addDataToSend(span.toThrift());
span.cancelTimer();
@@ -116,13 +127,13 @@ public final class Trace {
public static void recordAttribute(final String key, final String value) {
recordAttibute(key, (Object) value);
}
public static void recordAttibute(final String key, final Object value) {
if (!tracingEnabled)
return;
try {
mutate(getTraceId(), new SpanUpdater() {
mutate(getTraceIdOrCreateNew(), new SpanUpdater() {
@Override
public Span updateSpan(Span span) {
span.addAnnotation(new HippoBinaryAnnotation(System.currentTimeMillis(), key, value));
@@ -144,8 +155,9 @@ public final class Trace {
public static void recordRpcName(final String service, final String rpc) {
if (!tracingEnabled)
return;
try {
mutate(getTraceId(), new SpanUpdater() {
mutate(getTraceIdOrCreateNew(), new SpanUpdater() {
@Override
public Span updateSpan(Span span) {
span.setServiceName(service);
@@ -163,7 +175,7 @@ public final class Trace {
return;
try {
mutate(getTraceId(), new SpanUpdater() {
mutate(getTraceIdOrCreateNew(), new SpanUpdater() {
@Override
public Span updateSpan(Span span) {
// set endpoint to both span and annotations
@@ -181,7 +193,7 @@ public final class Trace {
return;
try {
mutate(getTraceId(), new SpanUpdater() {
mutate(getTraceIdOrCreateNew(), new SpanUpdater() {
@Override
public Span updateSpan(Span span) {
span.addAnnotation(new HippoAnnotation(System.currentTimeMillis(), value, duration));
@@ -3,7 +3,7 @@ package com.profiler.context;
import java.util.UUID;
public class TraceID {
private UUID traceId;
private UUID id;
private long parentSpanId;
private long spanId;
private boolean sampled;
@@ -14,21 +14,21 @@ public class TraceID {
return new TraceID(uuid, SpanID.NULL, SpanID.newSpanID(), false, 0);
}
public TraceID(UUID traceId, long parentSpanId, long spanId, boolean sampled, int flags) {
this.traceId = traceId;
public TraceID(UUID id, long parentSpanId, long spanId, boolean sampled, int flags) {
this.id = id;
this.parentSpanId = parentSpanId;
this.spanId = spanId;
this.sampled = sampled;
this.flags = flags;
}
public UUID getTraceId() {
return traceId;
public UUID getId() {
return id;
}
public TraceKey getTraceKey() {
long most = traceId.getMostSignificantBits();
long least = traceId.getLeastSignificantBits();
long most = id.getMostSignificantBits();
long least = id.getLeastSignificantBits();
return new TraceKey(most, least);
}
@@ -83,7 +83,7 @@ public class TraceID {
}
public void setTraceId(UUID traceId) {
this.traceId = traceId;
this.id = traceId;
}
public void setParentSpanId(long parentSpanId) {
@@ -107,7 +107,7 @@ public class TraceID {
StringBuilder sb = new StringBuilder();
sb.append("TraceID={");
sb.append("traceId=").append(traceId);
sb.append("id=").append(id);
sb.append(", parentSpanId=").append(parentSpanId);
sb.append(", spanId=").append(spanId);
sb.append(", sampled=").append(sampled);
@@ -4,6 +4,7 @@ import java.security.ProtectionDomain;
import java.util.logging.Level;
import java.util.logging.Logger;
import com.profiler.StopWatch;
import com.profiler.interceptor.bci.ByteCodeInstrumentor;
import com.profiler.interceptor.bci.InstrumentClass;
import com.profiler.modifier.AbstractModifier;
@@ -40,7 +41,7 @@ public class ArcusClientModifier extends AbstractModifier {
*/
aClass.addTraceVariable("__traceId", "__setTraceId", "__getTraceId", "com.profiler.context.TraceID");
aClass.addTraceVariable("__nextTraceId", "__setNextTraceId", "__getNextTraceId", "com.profiler.context.TraceID");
aClass.insertCodeAfterConstructor(null, "{ __setTraceId(com.profiler.context.Trace.getCurrentTraceId()); __setNextTraceId(com.profiler.context.Trace.getNextId()); }");
aClass.insertCodeAfterConstructor(null, "{ __setTraceId(com.profiler.context.Trace.getCurrentTraceId()); __setNextTraceId(com.profiler.context.Trace.getNextTraceId()); }");
aClass.insertCodeBeforeMethod("transitionState", new String[] { "net.spy.memcached.ops.OperationState" }, getTransitionStateAfterCode());
@@ -79,6 +80,10 @@ public class ArcusClientModifier extends AbstractModifier {
// code.append("System.out.println(\"\");");
code.append("if (newState == net.spy.memcached.ops.OperationState.READING) {");
// TODO: remove, debugging
code.append("System.out.println(\"\\n\\n\\nINVOKE ARCUS BEFORE ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\");");
code.append(" java.net.SocketAddress socketAddress = handlingNode.getSocketAddress();");
code.append(" if (socketAddress instanceof java.net.InetSocketAddress) {");
code.append(" java.net.InetSocketAddress addr = (java.net.InetSocketAddress) handlingNode.getSocketAddress();");
@@ -87,10 +92,15 @@ public class ArcusClientModifier extends AbstractModifier {
code.append(" com.profiler.context.Trace.recordRpcName(\"arcus\", \"\");");
code.append(" com.profiler.context.Trace.recordAttribute(\"arcus.command\", ((cmd == null) ? \"UNKNOWN\" : new String(cmd.array())));");
code.append(" System.out.println(\"CS\");");
code.append(" com.profiler.StopWatch.start(this.hashCode());");
code.append(" com.profiler.context.Trace.record(com.profiler.context.Annotation.ClientSend);");
code.append("} else if (newState == net.spy.memcached.ops.OperationState.COMPLETE) {");
code.append(" System.out.println(\"CR\");");
code.append(" com.profiler.context.Trace.record(com.profiler.context.Annotation.ClientRecv);");
code.append(" com.profiler.context.Trace.record(com.profiler.context.Annotation.ClientRecv, com.profiler.StopWatch.stopAndGetElapsed(this.hashCode()));");
// TODO: remove, debugging
code.append("System.out.println(\"\\n\\n\\nINVOKE ARCUS AFTER ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\");");
code.append("}");
code.append("}");
@@ -27,15 +27,15 @@ public class ExecuteMethodInterceptor implements StaticAroundInterceptor {
@Override
public void before(Object target, String className, String methodName, Object[] args) {
System.out.println("\n\n\n\nHTTP BEFORE");
System.out.println("\n\n\n\nINVOKE HTTP START ----------------------------------------------------------------------------------------------------------------------------------------------------");
HttpHost host = (HttpHost) args[0];
HttpRequest request = (HttpRequest) args[1];
TraceID nextId = Trace.getNextId();
TraceID nextId = Trace.getNextTraceId();
// UUID format을 그대로.
request.addHeader(Header.HTTP_TRACE_ID.toString(), nextId.getTraceId().toString());
request.addHeader(Header.HTTP_TRACE_ID.toString(), nextId.getId().toString());
request.addHeader(Header.HTTP_SPAN_ID.toString(), Long.toString(nextId.getSpanId()));
request.addHeader(Header.HTTP_PARENT_SPAN_ID.toString(), Long.toString(nextId.getParentSpanId()));
request.addHeader(Header.HTTP_SAMPLED.toString(), String.valueOf(nextId.isSampled()));
@@ -51,7 +51,7 @@ public class ExecuteMethodInterceptor implements StaticAroundInterceptor {
@Override
public void after(Object target, String className, String methodName, Object[] args, Object result) {
System.out.println("\n\n\n\nHTTP AFTER");
Trace.record(Annotation.ClientRecv, StopWatch.stopAndGetElapsed("ExecuteMethodInterceptor"));
System.out.println("\n\n\n\nINVOKE HTTP END ----------------------------------------------------------------------------------------------------------------------------------------------------");
}
}
@@ -5,6 +5,7 @@ import java.util.UUID;
import javax.servlet.http.HttpServletRequest;
import com.profiler.StopWatch;
import com.profiler.context.Annotation;
import com.profiler.context.Header;
import com.profiler.context.SpanID;
@@ -12,45 +13,33 @@ import com.profiler.context.Trace;
import com.profiler.context.TraceID;
import com.profiler.interceptor.StaticAroundInterceptor;
import com.profiler.trace.RequestTracer;
import com.profiler.util.NamedThreadLocal;
import com.profiler.util.NumberUtils;
public class InvokeMethodInterceptor implements StaticAroundInterceptor {
private ThreadLocal<Long> start = new NamedThreadLocal<Long>("InvokeMethodInterceptor-starttime");
@Override
public void before(Object target, String className, String methodName, Object[] args) {
try {
HttpServletRequest request = (HttpServletRequest) args[0];
String requestURL = request.getRequestURI();
String clientIP = request.getRemoteAddr();
String parameters = getParameter(request);
String parameters = getRequestParameter(request);
UUID traceID = getTraceId(request);
if (traceID != null) {
long parentSpanID = NumberUtils.parseLong(request.getHeader(Header.HTTP_PARENT_SPAN_ID.toString()), SpanID.NULL);
long spanID = NumberUtils.parseLong(request.getHeader(Header.HTTP_SPAN_ID.toString()), SpanID.NULL);
boolean sampled = Boolean.parseBoolean(request.getHeader(Header.HTTP_SAMPLED.toString()));
int flags = NumberUtils.parseInteger(request.getHeader(Header.HTTP_FLAGS.toString()), 0);
TraceID id = new TraceID(traceID, parentSpanID, spanID, sampled, flags);
// TODO : refactor this, just for debug
System.out.println("\n\n\ngot a traceid. traceid=" + id + "\n\n\n");
Trace.setTraceId(id);
TraceID traceId = populateTraceIdFromRequest(request);
if (traceId != null) {
Trace.setTraceId(traceId);
} else {
Trace.setTraceId(TraceID.newTraceId());
}
Trace.recordRpcName("tomcat", requestURL);
Trace.recordEndPoint(request.getLocalAddr(), request.getLocalPort());
Trace.recordMessage("Parameter=" + parameters);
Trace.recordAttibute("http.params", parameters);
Trace.record(Annotation.ServerRecv);
RequestTracer.startTransaction(requestURL, clientIP, System.currentTimeMillis(), parameters);
start.set(System.currentTimeMillis());
StopWatch.start("InvokeMethodInterceptor-starttime");
} catch (Exception e) {
e.printStackTrace();
}
@@ -59,24 +48,38 @@ public class InvokeMethodInterceptor implements StaticAroundInterceptor {
@Override
public void after(Object target, String className, String methodName, Object[] args, Object result) {
// TODO result 가 Exception 타입일경우 호출 실패임.
Trace.record(Annotation.ServerSend, System.currentTimeMillis() - start.get());
start.remove();
Trace.record(Annotation.ServerSend, StopWatch.stopAndGetElapsed("InvokeMethodInterceptor-starttime"));
RequestTracer.endTransaction();
}
private UUID getTraceId(HttpServletRequest request) {
String header = request.getHeader(Header.HTTP_TRACE_ID.toString());
if (header == null) {
return null;
}
try {
return UUID.fromString(header);
} catch (IllegalArgumentException e) {
/**
* Pupulate source trace from HTTP Header.
*
* @param request
* @return
*/
private TraceID populateTraceIdFromRequest(HttpServletRequest request) {
String strUUID = request.getHeader(Header.HTTP_TRACE_ID.toString());
if (strUUID != null) {
UUID uuid = UUID.fromString(strUUID);
long parentSpanID = NumberUtils.parseLong(request.getHeader(Header.HTTP_PARENT_SPAN_ID.toString()), SpanID.NULL);
long spanID = NumberUtils.parseLong(request.getHeader(Header.HTTP_SPAN_ID.toString()), SpanID.NULL);
boolean sampled = Boolean.parseBoolean(request.getHeader(Header.HTTP_SAMPLED.toString()));
int flags = NumberUtils.parseInteger(request.getHeader(Header.HTTP_FLAGS.toString()), 0);
TraceID id = new TraceID(uuid, parentSpanID, spanID, sampled, flags);
// TODO : remove this, just for debug
System.out.println("\nGOT A TRACEID. TRACEID=" + id + "\n\n");
return id;
} else {
return null;
}
}
private String getParameter(HttpServletRequest request) {
private String getRequestParameter(HttpServletRequest request) {
Enumeration<?> attrs = request.getParameterNames();
StringBuilder params = new StringBuilder();