package com.yirendai.infra.cicada.capture;
import com.yirendai.infra.cicada.entity.trace.Endpoint;
import com.yirendai.infra.cicada.entity.trace.Span;
import com.yirendai.infra.cicada.utils.IpUtils;
import com.yirendai.infra.cicada.utils.SpringContextUtil;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
@Aspect
public class TraceableAop {
private static final String DEFAULT_APP_NAME = "traceable";
@Around("execution(* *(..)) && "
+ "(@within(com.yirendai.infra.cicada.capture.Traceable) ||"
+ " @annotation(com.yirendai.infra.cicada.capture.Traceable))")
public Object around(final ProceedingJoinPoint point) throws java.lang.Throwable {
final long start = System.currentTimeMillis();
final String localIp = IpUtils.getRealIpWithStaticCache();
final int localPort = 0;
final Endpoint endpoint = new Endpoint(localIp, localPort);
final String className = point.getTarget().getClass().getCanonicalName();
final String methodName = point.getSignature().getName();
final String appName = SpringContextUtil.getAppName(DEFAULT_APP_NAME);
final Tracer tracer = Tracer.getInstance();
final Span parentSpan = tracer.getParentSpan();
final boolean createSpan = parentSpan == null;
Span span = null;
if (createSpan) {
final Span traceCtx = tracer.getAndRemoveTraceCtx();
if (traceCtx != null) {
final String traceId = traceCtx.getTraceId();
final String pid = traceCtx.getParentId();
final String id = traceCtx.getId();
final boolean sample = traceId != null;
span = tracer.genSpan(appName, className, methodName, traceId, pid, id, sample);
} else {
span = tracer.newSpan(appName, className, methodName);
}
tracer.serverReceiveRecord(span, endpoint, start);
}
Object result = null;
try {
result = point.proceed();
} catch (Exception ex) {
if (createSpan) {
span.addException(className, methodName, ex, endpoint);
} else {
tracer.addBinaryAnnotation(className, methodName, ex);
}
throw ex;
} finally {
final long end = System.currentTimeMillis();
if (createSpan) {
tracer.serverSendRecord(span, endpoint, end);
} else {
tracer.addBinaryAnnotation(className, methodName, (int) (end - start));
}
}
return result;
}
}