package org.skywalking.apm.plugin.motan; import com.weibo.api.motan.rpc.Request; import com.weibo.api.motan.rpc.Response; import com.weibo.api.motan.rpc.URL; 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.ConstructorInvokeContext; import org.skywalking.apm.agent.core.plugin.interceptor.enhance.InstanceConstructorInterceptor; 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.trace.Span; import org.skywalking.apm.trace.tag.Tags; /** * {@link MotanProviderInterceptor} create span by fetch request url from * {@link EnhancedClassInstanceContext#context} and transport serialized context * data to provider side through {@link Request#setAttachment(String, String)}. * * @author zhangxin */ public class MotanConsumerInterceptor implements InstanceConstructorInterceptor, InstanceMethodsAroundInterceptor { /** * The */ private static final String KEY_NAME_OF_REQUEST_URL = "REQUEST_URL"; /** * The {@link Request#getAttachments()} key. It maps to the serialized {@link ContextCarrier}. */ private static final String ATTACHMENT_KEY_OF_CONTEXT_DATA = "SWTraceContext"; /** * Motan component */ private static final String MOTAN_COMPONENT = "Motan"; @Override public void onConstruct(EnhancedClassInstanceContext context, ConstructorInvokeContext interceptorContext) { context.set(KEY_NAME_OF_REQUEST_URL, interceptorContext.allArguments()[1]); } @Override public void beforeMethod(EnhancedClassInstanceContext context, InstanceMethodInvokeContext interceptorContext, MethodInterceptResult result) { URL url = (URL) context.get(KEY_NAME_OF_REQUEST_URL); Request request = (Request) interceptorContext.allArguments()[0]; if (url != null) { Span span = ContextManager.createSpan(generateOperationName(url, request)); Tags.PEER_HOST.set(span, url.getHost()); Tags.PEER_PORT.set(span, url.getPort()); Tags.COMPONENT.set(span, MOTAN_COMPONENT); Tags.URL.set(span, url.getIdentity()); Tags.SPAN_KIND.set(span, Tags.SPAN_KIND_CLIENT); Tags.SPAN_LAYER.asRPCFramework(span); ContextCarrier contextCarrier = new ContextCarrier(); ContextManager.inject(contextCarrier); request.setAttachment(ATTACHMENT_KEY_OF_CONTEXT_DATA, contextCarrier.serialize()); } } @Override public Object afterMethod(EnhancedClassInstanceContext context, InstanceMethodInvokeContext interceptorContext, Object ret) { Response response = (Response) ret; if (response != null && response.getException() != null) { Span span = ContextManager.activeSpan(); Tags.ERROR.set(span, true); span.log(response.getException()); } ContextManager.stopSpan(); return ret; } @Override public void handleMethodException(Throwable t, EnhancedClassInstanceContext context, InstanceMethodInvokeContext interceptorContext) { ContextManager.activeSpan().log(t); } /** * Generate operation name. * * @return operation name. */ private static String generateOperationName(URL serviceURI, Request request) { return new StringBuilder(serviceURI.getPath()).append(".").append(request.getMethodName()).append("(") .append(request.getParamtersDesc()).append(")").toString(); } }