Skip to content

Commit

Permalink
add Span/SpanEvent wrapper
Browse files Browse the repository at this point in the history
  • Loading branch information
jaehong-kim committed Jun 29, 2015
1 parent 17a1c6e commit fe7e11d
Show file tree
Hide file tree
Showing 11 changed files with 569 additions and 510 deletions.
Expand Up @@ -32,4 +32,6 @@ public interface StackOperation {

void traceBlockEnd(int stackId);
boolean isRootStack();
int getStackFrameId();

}
Expand Up @@ -19,7 +19,20 @@
/**
* @author emeroad
*/
public interface Trace extends RecordableTrace, StackOperation {
public interface Trace extends StackOperation {

TraceId getTraceId();

AsyncTraceId getAsyncTraceId();

boolean canSampled();

boolean isRoot();

boolean isAsync();

long getTraceStartTime();


void close();
}
@@ -0,0 +1,107 @@
package com.navercorp.pinpoint.profiler.context;

import com.navercorp.pinpoint.bootstrap.context.TraceContext;
import com.navercorp.pinpoint.bootstrap.interceptor.MethodDescriptor;
import com.navercorp.pinpoint.bootstrap.util.StringUtils;
import com.navercorp.pinpoint.common.trace.AnnotationKey;

public abstract class AbstractRecorderWrapper {

protected final TraceContext traceContext;

public AbstractRecorderWrapper(final TraceContext traceContext) {
this.traceContext = traceContext;
}

public void recordException(Throwable th) {
if (th == null) {
return;
}
final String drop = StringUtils.drop(th.getMessage(), 256);
// An exception that is an instance of a proxy class could make something wrong because the class name will vary.
final int exceptionId = traceContext.cacheString(th.getClass().getName());
setExceptionInfo(exceptionId, drop);
}

abstract void setExceptionInfo(int exceptionClassId, String exceptionMessage);

public void recordApi(MethodDescriptor methodDescriptor) {
if (methodDescriptor == null) {
return;
}
if (methodDescriptor.getApiId() == 0) {
recordAttribute(AnnotationKey.API, methodDescriptor.getFullName());
} else {
recordApiId(methodDescriptor.getApiId());
}
}

public void recordApi(MethodDescriptor methodDescriptor, Object[] args) {
recordApi(methodDescriptor);
recordArgs(args);
}

public void recordApi(MethodDescriptor methodDescriptor, Object args, int index) {
recordApi(methodDescriptor);
recordSingleArg(args, index);
}

public void recordApi(MethodDescriptor methodDescriptor, Object[] args, int start, int end) {
recordApi(methodDescriptor);
recordArgs(args, start, end);
}

public void recordApiCachedString(MethodDescriptor methodDescriptor, String args, int index) {
recordApi(methodDescriptor);
recordSingleCachedString(args, index);
}

abstract void recordApiId(final int apiId);

private void recordArgs(Object[] args, int start, int end) {
if (args != null) {
int max = Math.min(Math.min(args.length, AnnotationKey.MAX_ARGS_SIZE), end);
for (int i = start; i < max; i++) {
recordAttribute(AnnotationKey.getArgs(i), args[i]);
}
// TODO How to handle if args length is greater than MAX_ARGS_SIZE?
}
}

private void recordSingleArg(Object args, int index) {
if (args != null) {
recordAttribute(AnnotationKey.getArgs(index), args);
}
}

private void recordSingleCachedString(String args, int index) {
if (args != null) {
int cacheId = traceContext.cacheString(args);
recordAttribute(AnnotationKey.getCachedArgs(index), cacheId);
}
}

private void recordArgs(Object[] args) {
if (args != null) {
int max = Math.min(args.length, AnnotationKey.MAX_ARGS_SIZE);
for (int i = 0; i < max; i++) {
recordAttribute(AnnotationKey.getArgs(i), args[i]);
}
// TODO How to handle if args length is greater than MAX_ARGS_SIZE?
}
}

public void recordAttribute(AnnotationKey key, String value) {
addAnnotation(new Annotation(key.getCode(), value));
}

public void recordAttribute(AnnotationKey key, int value) {
addAnnotation(new Annotation(key.getCode(), value));
}

public void recordAttribute(AnnotationKey key, Object value) {
addAnnotation(new Annotation(key.getCode(), value));
}

abstract void addAnnotation(Annotation annotation);
}
Expand Up @@ -22,6 +22,7 @@
import org.slf4j.LoggerFactory;

import java.util.Arrays;
import java.util.Stack;

/**
* @author netspider
Expand All @@ -32,13 +33,13 @@ public class CallStack {
private static final Logger logger = LoggerFactory.getLogger(CallStack.class);

private static final int STACK_SIZE = 8;
private static final int DEFAULT_INDEX = -1;

private final Span span;

private StackFrame[] stack = new StackFrame[STACK_SIZE];

private SpanEvent[] stack = new SpanEvent[STACK_SIZE];

private int index = -1;
private int index = DEFAULT_INDEX;

public CallStack(Span span) {
if (span == null) {
Expand All @@ -52,106 +53,58 @@ public Span getSpan() {
}

public int getIndex() {
return index;
}


public StackFrame getCurrentStackFrame() {
return stack[index];
}

public StackFrame getParentStackFrame() {
if (index > 0) {
return stack[index - 1];
}
return null;
}

public void setStackFrame(StackFrame stackFrame) {
if (stackFrame == null) {
throw new NullPointerException("stackFrame must not be null");
}
stack[index] = stackFrame;
return index;
}

public int push() {
public int push(final SpanEvent spanEvent) {
checkExtend(index + 1);
return ++index;
stack[++index] = spanEvent;

return index;
}

private void checkExtend(final int index) {
final StackFrame[] originalStack = this.stack;
if (index >= originalStack.length) {
private void checkExtend(final int size) {
final SpanEvent[] originalStack = this.stack;
if (size >= originalStack.length) {
final int copyStackSize = originalStack.length << 1;
final StackFrame[] copyStack = new StackFrame[copyStackSize];
final SpanEvent[] copyStack = new SpanEvent[copyStackSize];
System.arraycopy(originalStack, 0, copyStack, 0, originalStack.length);
this.stack = copyStack;
}
}

public int getStackFrameIndex() {
return index;
}

public void popRoot() {
pop("popRoot");
// check empty root index
if (index != -1) {
PinpointException ex = createStackException("invalid root stack found", this.index);
throw ex;
public SpanEvent pop() {
final SpanEvent spanEvent = peek();
if (spanEvent != null) {
stack[index] = null;
--index;
}
}

public StackFrame pop() {
pop("pop");
if (index == -1) {
return null;
} else {
return getCurrentStackFrame();
}
return spanEvent;
}

private void pop(String stackApiPoint) {
final int currentIndex = this.index;
final StackFrame[] currentStack = this.stack;
if (currentIndex >= 0) {
currentStack[currentIndex] = null;
this.index = currentIndex - 1;
} else {
PinpointException ex = createStackException(stackApiPoint, this.index);
throw ex;
}
}


private PinpointException createStackException(String stackApiPoint, final int index) {
final PinpointException ex = new PinpointException("Profiler CallStack check. index:" + index + " stackApiPoint:" + stackApiPoint);
if (logger.isWarnEnabled()) {
// need to dump stack.
logger.warn("invalid callStack found stack dump:{}", this, ex);
public SpanEvent peek() {
if (index == DEFAULT_INDEX) {
return null;
}
return ex;
}


public void currentStackFrameClear() {
stack[index] = null;
return stack[index];
}

public StackFrame[] copyStackFrame() {
// without synchronization arraycopy, last index is null reference
final StackFrame[] currentStack = this.stack;
final StackFrame[] copyStack = new StackFrame[currentStack.length];
System.arraycopy(currentStack, 0, copyStack, 0, currentStack.length);
return copyStack;
public boolean empty() {
return index == DEFAULT_INDEX;
}

@Override
public String toString() {
final StackFrame[] stack = this.stack;
return "CallStack{" +
"stack=" + (stack == null ? null : Arrays.toString(stack)) +
", index=" + index +
'}';
StringBuilder builder = new StringBuilder();
builder.append("{span=");
builder.append(span);
builder.append(", stack=");
builder.append(Arrays.toString(stack));
builder.append(", index=");
builder.append(index);
builder.append("}");
return builder.toString();
}
}

0 comments on commit fe7e11d

Please sign in to comment.