package com.navercorp.pinpoint.plugin.hystrix.interceptor;
import com.navercorp.pinpoint.bootstrap.async.AsyncTraceIdAccessor;
import com.navercorp.pinpoint.bootstrap.context.*;
import com.navercorp.pinpoint.bootstrap.interceptor.AroundInterceptor;
import com.navercorp.pinpoint.bootstrap.logging.PLogger;
import com.navercorp.pinpoint.bootstrap.logging.PLoggerFactory;
import com.navercorp.pinpoint.plugin.hystrix.HystrixPluginConstants;
/**
* @author Jiaqi Feng
*/
public class HystrixCommandQueueInterceptor implements AroundInterceptor {
protected final PLogger logger = PLoggerFactory.getLogger(getClass());
protected final boolean isDebug = logger.isDebugEnabled();
private final MethodDescriptor descriptor;
private final TraceContext traceContext;
public HystrixCommandQueueInterceptor(TraceContext traceContext, MethodDescriptor descriptor) {
this.traceContext = traceContext;
this.descriptor = descriptor;
}
@Override
public void before(Object target, Object[] args) {
if (isDebug) {
logger.beforeInterceptor(target,args);
}
Trace trace = traceContext.currentTraceObject();
if (trace == null) {
return;
}
SpanEventRecorder recorder = trace.traceBlockBegin();
recorder.recordServiceType(HystrixPluginConstants.HYSTRIX_SERVICE_TYPE);
recorder.recordApi(descriptor);
recorder.recordAttribute(HystrixPluginConstants.HYSTRIX_COMMAND_ANNOTATION_KEY, target.getClass().getSimpleName());
// To trace async invocations, you have to get async trace id like below.
AsyncTraceId asyncTraceId = trace.getAsyncTraceId();
// Then record the AsyncTraceId as next async id.
recorder.recordNextAsyncId(asyncTraceId.getAsyncId());
// Finally, you have to pass the AsyncTraceId to the thread which handles the async task.
((AsyncTraceIdAccessor)target)._$PINPOINT$_setAsyncTraceId(asyncTraceId);
}
@Override
public void after(Object target, Object[] args, Object result, Throwable throwable) {
if (isDebug) {
logger.afterInterceptor(target, args, result, throwable);
}
Trace trace = traceContext.currentTraceObject();
if (trace == null) {
return;
}
try {
if (throwable != null) {
SpanEventRecorder recorder = trace.currentSpanEventRecorder();
recorder.recordException(throwable);
}
} finally {
trace.traceBlockEnd();
}
}
}