package org.skywalking.apm.plugin.motan;
import com.weibo.api.motan.rpc.Request;
import com.weibo.api.motan.rpc.Response;
import org.skywalking.apm.agent.core.context.ContextCarrier;
import org.skywalking.apm.agent.core.context.ContextManager;
import org.skywalking.apm.agent.core.plugin.interceptor.EnhancedClassInstanceContext;
import org.skywalking.apm.agent.core.plugin.interceptor.enhance.InstanceMethodInvokeContext;
import org.skywalking.apm.agent.core.plugin.interceptor.enhance.InstanceMethodsAroundInterceptor;
import org.skywalking.apm.agent.core.plugin.interceptor.enhance.MethodInterceptResult;
import org.skywalking.apm.util.StringUtil;
import org.skywalking.apm.trace.Span;
import org.skywalking.apm.trace.tag.Tags;
/**
* Current trace segment will ref the trace segment if the serialized trace context that fetch from {@link
* Request#getAttachments()} is not null.
* <p>
* {@link MotanConsumerInterceptor} intercept all constructor of {@link com.weibo.api.motan.rpc.AbstractProvider} for
* record the request url from consumer side.
*
* @author zhangxin
*/
public class MotanProviderInterceptor implements InstanceMethodsAroundInterceptor {
/**
* Attachment key of the serialized context data.
*/
private static final String ATTACHMENT_KEY_OF_CONTEXT_DATA = "SWTraceContext";
/**
* Motan component
*/
private static final String MOTAN_COMPONENT = "Motan";
@Override
public void beforeMethod(EnhancedClassInstanceContext context, InstanceMethodInvokeContext interceptorContext,
MethodInterceptResult result) {
Request request = (Request) interceptorContext.allArguments()[0];
Span span = ContextManager.createSpan(generateViewPoint(request));
Tags.COMPONENT.set(span, MOTAN_COMPONENT);
Tags.SPAN_KIND.set(span, Tags.SPAN_KIND_SERVER);
Tags.SPAN_LAYER.asRPCFramework(span);
String serializedContextData = request.getAttachments().get(ATTACHMENT_KEY_OF_CONTEXT_DATA);
if (!StringUtil.isEmpty(serializedContextData)) {
ContextManager.extract(new ContextCarrier().deserialize(serializedContextData));
}
}
@Override
public Object afterMethod(EnhancedClassInstanceContext context, InstanceMethodInvokeContext interceptorContext,
Object ret) {
Response response = (Response) ret;
if (response != null && response.getException() != null) {
Span span = ContextManager.activeSpan();
span.log(response.getException());
Tags.ERROR.set(span, true);
}
ContextManager.stopSpan();
return ret;
}
@Override
public void handleMethodException(Throwable t, EnhancedClassInstanceContext context,
InstanceMethodInvokeContext interceptorContext) {
ContextManager.activeSpan().log(t);
}
private static String generateViewPoint(Request request) {
StringBuilder viewPoint = new StringBuilder(request.getInterfaceName());
viewPoint.append("." + request.getMethodName());
viewPoint.append("(" + request.getParamtersDesc() + ")");
return viewPoint.toString();
}
}