diff --git a/skywalking-collector/skywalking-sdk-plugin/motan-plugin/pom.xml b/skywalking-collector/skywalking-sdk-plugin/motan-plugin/pom.xml
new file mode 100644
index 000000000..5459c261a
--- /dev/null
+++ b/skywalking-collector/skywalking-sdk-plugin/motan-plugin/pom.xml
@@ -0,0 +1,48 @@
+
+ * service URL : motan://172.18.80.208:0/org.a.eye.skywalking.motan + * .FooService?group=default_rpc + * execute method : helloWorld + * execute parameter: java.lang.String,java.lang.String + *
+ *
+ * view point: motan://172.18.80.208:0/org.a.eye.skywalking.motan.FooService.helloWorld
+ * (java.lang.String,java.lang.String)?group=default_rpc
+ *
+ * @param serviceURI such as: motan://172.18.80.208:0/org.a.eye.skywalking.motan.FooService?group=default_rpc
+ * @param request
+ * @return such as: motan://172.18.80.208:0/org.a.eye.skywalking.motan.FooService.helloWorld
+ * (java.lang.String,java.lang.String)?group=default_rpc
+ */
+ private static String generateViewPoint(URL serviceURI, Request request) {
+ StringBuilder viewPoint = new StringBuilder(serviceURI.getUri());
+ viewPoint.append("." + request.getMethodName());
+ viewPoint.append("(" + request.getParamtersDesc() + ")?group=" + serviceURI.getGroup());
+ return viewPoint.toString();
+ }
+
+ /**
+ * @param request
+ * @param serviceURI such as: motan://172.18.80.208:0/org.a.eye.skywalking.motan.FooService?group=default_rpc
+ * @return
+ */
+ public static Identification generateIdentify(Request request, URL serviceURI) {
+ return Identification.newBuilder().viewPoint(generateViewPoint(serviceURI, request))
+ .spanType(MotanBuriedPointType.instance()).build();
+ }
+}
diff --git a/skywalking-collector/skywalking-sdk-plugin/motan-plugin/src/main/java/com/a/eye/skywalking/plugin/motan/MotanBuriedPointType.java b/skywalking-collector/skywalking-sdk-plugin/motan-plugin/src/main/java/com/a/eye/skywalking/plugin/motan/MotanBuriedPointType.java
new file mode 100644
index 000000000..e7e1b5786
--- /dev/null
+++ b/skywalking-collector/skywalking-sdk-plugin/motan-plugin/src/main/java/com/a/eye/skywalking/plugin/motan/MotanBuriedPointType.java
@@ -0,0 +1,32 @@
+package com.a.eye.skywalking.plugin.motan;
+
+import com.a.eye.skywalking.api.IBuriedPointType;
+import com.a.eye.skywalking.protocol.common.CallType;
+
+public class MotanBuriedPointType implements IBuriedPointType {
+
+ private static MotanBuriedPointType motanBuriedPointType;
+
+ public static IBuriedPointType instance() {
+ if (motanBuriedPointType == null) {
+ motanBuriedPointType = new MotanBuriedPointType();
+ }
+
+ return motanBuriedPointType;
+ }
+
+ @Override
+ public String getTypeName() {
+ return "M";
+ }
+
+ @Override
+ public CallType getCallType() {
+ return CallType.SYNC;
+ }
+
+ private MotanBuriedPointType() {
+ //Non
+ }
+
+}
diff --git a/skywalking-collector/skywalking-sdk-plugin/motan-plugin/src/main/java/com/a/eye/skywalking/plugin/motan/MotanClientInterceptor.java b/skywalking-collector/skywalking-sdk-plugin/motan-plugin/src/main/java/com/a/eye/skywalking/plugin/motan/MotanClientInterceptor.java
new file mode 100644
index 000000000..f70462bf7
--- /dev/null
+++ b/skywalking-collector/skywalking-sdk-plugin/motan-plugin/src/main/java/com/a/eye/skywalking/plugin/motan/MotanClientInterceptor.java
@@ -0,0 +1,49 @@
+package com.a.eye.skywalking.plugin.motan;
+
+import com.a.eye.skywalking.invoke.monitor.RPCClientInvokeMonitor;
+import com.a.eye.skywalking.model.ContextData;
+import com.a.eye.skywalking.plugin.interceptor.EnhancedClassInstanceContext;
+import com.a.eye.skywalking.plugin.interceptor.enhance.ConstructorInvokeContext;
+import com.a.eye.skywalking.plugin.interceptor.enhance.InstanceMethodInvokeContext;
+import com.a.eye.skywalking.plugin.interceptor.enhance.InstanceMethodsAroundInterceptor;
+import com.a.eye.skywalking.plugin.interceptor.enhance.MethodInterceptResult;
+import com.weibo.api.motan.rpc.Request;
+import com.weibo.api.motan.rpc.URL;
+
+import static com.a.eye.skywalking.plugin.motan.IdentificationUtil.generateIdentify;
+
+/**
+ * Motan client interceptor
+ */
+public class MotanClientInterceptor implements InstanceMethodsAroundInterceptor {
+ @Override
+ public void onConstruct(EnhancedClassInstanceContext context, ConstructorInvokeContext interceptorContext) {
+ context.set("serviceURI", interceptorContext.allArguments()[1]);
+ }
+
+ @Override
+ public void beforeMethod(EnhancedClassInstanceContext context, InstanceMethodInvokeContext interceptorContext,
+ MethodInterceptResult result) {
+ Request request = (Request) interceptorContext.allArguments()[0];
+ if (request != null) {
+ ContextData contextData = new RPCClientInvokeMonitor()
+ .beforeInvoke(generateIdentify(request, (URL) context.get("serviceURI")));
+ String contextDataStr = contextData.toString();
+ request.setAttachment("contextData", contextDataStr);
+ }
+ }
+
+ @Override
+ public Object afterMethod(EnhancedClassInstanceContext context, InstanceMethodInvokeContext interceptorContext,
+ Object ret) {
+ new RPCClientInvokeMonitor().afterInvoke();
+ return ret;
+ }
+
+ @Override
+ public void handleMethodException(Throwable t, EnhancedClassInstanceContext context,
+ InstanceMethodInvokeContext interceptorContext) {
+ new RPCClientInvokeMonitor().occurException(t);
+ }
+
+}
diff --git a/skywalking-collector/skywalking-sdk-plugin/motan-plugin/src/main/java/com/a/eye/skywalking/plugin/motan/MotanServerInterceptor.java b/skywalking-collector/skywalking-sdk-plugin/motan-plugin/src/main/java/com/a/eye/skywalking/plugin/motan/MotanServerInterceptor.java
new file mode 100644
index 000000000..1d0d49c64
--- /dev/null
+++ b/skywalking-collector/skywalking-sdk-plugin/motan-plugin/src/main/java/com/a/eye/skywalking/plugin/motan/MotanServerInterceptor.java
@@ -0,0 +1,41 @@
+package com.a.eye.skywalking.plugin.motan;
+
+import com.a.eye.skywalking.invoke.monitor.RPCServerInvokeMonitor;
+import com.a.eye.skywalking.model.ContextData;
+import com.a.eye.skywalking.plugin.interceptor.EnhancedClassInstanceContext;
+import com.a.eye.skywalking.plugin.interceptor.enhance.ConstructorInvokeContext;
+import com.a.eye.skywalking.plugin.interceptor.enhance.InstanceMethodInvokeContext;
+import com.a.eye.skywalking.plugin.interceptor.enhance.InstanceMethodsAroundInterceptor;
+import com.a.eye.skywalking.plugin.interceptor.enhance.MethodInterceptResult;
+import com.weibo.api.motan.rpc.Request;
+import com.weibo.api.motan.rpc.URL;
+
+public class MotanServerInterceptor implements InstanceMethodsAroundInterceptor {
+ @Override
+ public void onConstruct(EnhancedClassInstanceContext context, ConstructorInvokeContext interceptorContext) {
+ context.set("serviceURI", interceptorContext.allArguments()[0]);
+ }
+
+ @Override
+ public void beforeMethod(EnhancedClassInstanceContext context, InstanceMethodInvokeContext interceptorContext,
+ MethodInterceptResult result) {
+ Request request = (Request) interceptorContext.allArguments()[0];
+ if (request != null) {
+ new RPCServerInvokeMonitor().beforeInvoke(new ContextData(request.getAttachments().get("contextData")),
+ IdentificationUtil.generateIdentify(request, (URL) context.get("serviceURI")));
+ }
+ }
+
+ @Override
+ public Object afterMethod(EnhancedClassInstanceContext context, InstanceMethodInvokeContext interceptorContext,
+ Object ret) {
+ new RPCServerInvokeMonitor().afterInvoke();
+ return ret;
+ }
+
+ @Override
+ public void handleMethodException(Throwable t, EnhancedClassInstanceContext context,
+ InstanceMethodInvokeContext interceptorContext) {
+ new RPCServerInvokeMonitor().occurException(t);
+ }
+}
diff --git a/skywalking-collector/skywalking-sdk-plugin/motan-plugin/src/main/java/com/a/eye/skywalking/plugin/motan/define/MotanClientDefine.java b/skywalking-collector/skywalking-sdk-plugin/motan-plugin/src/main/java/com/a/eye/skywalking/plugin/motan/define/MotanClientDefine.java
new file mode 100644
index 000000000..5fbf9cc42
--- /dev/null
+++ b/skywalking-collector/skywalking-sdk-plugin/motan-plugin/src/main/java/com/a/eye/skywalking/plugin/motan/define/MotanClientDefine.java
@@ -0,0 +1,22 @@
+package com.a.eye.skywalking.plugin.motan.define;
+
+import com.a.eye.skywalking.plugin.interceptor.MethodMatcher;
+import com.a.eye.skywalking.plugin.interceptor.enhance.ClassInstanceMethodsEnhancePluginDefine;
+import com.a.eye.skywalking.plugin.interceptor.matcher.SimpleMethodMatcher;
+
+public class MotanClientDefine extends ClassInstanceMethodsEnhancePluginDefine {
+ @Override
+ protected String enhanceClassName() {
+ return "com.weibo.api.motan.rpc.AbstractReferer";
+ }
+
+ @Override
+ protected MethodMatcher[] getInstanceMethodsMatchers() {
+ return new MethodMatcher[] {new SimpleMethodMatcher("call")};
+ }
+
+ @Override
+ protected String getInstanceMethodsInterceptor() {
+ return "com.a.eye.skywalking.plugin.motan.MotanClientInterceptor";
+ }
+}
diff --git a/skywalking-collector/skywalking-sdk-plugin/motan-plugin/src/main/java/com/a/eye/skywalking/plugin/motan/define/MotanServerDefine.java b/skywalking-collector/skywalking-sdk-plugin/motan-plugin/src/main/java/com/a/eye/skywalking/plugin/motan/define/MotanServerDefine.java
new file mode 100644
index 000000000..703196f83
--- /dev/null
+++ b/skywalking-collector/skywalking-sdk-plugin/motan-plugin/src/main/java/com/a/eye/skywalking/plugin/motan/define/MotanServerDefine.java
@@ -0,0 +1,23 @@
+package com.a.eye.skywalking.plugin.motan.define;
+
+import com.a.eye.skywalking.plugin.interceptor.MethodMatcher;
+import com.a.eye.skywalking.plugin.interceptor.enhance.ClassInstanceMethodsEnhancePluginDefine;
+import com.a.eye.skywalking.plugin.interceptor.matcher.SimpleMethodMatcher;
+
+public class MotanServerDefine extends ClassInstanceMethodsEnhancePluginDefine {
+
+ @Override
+ protected String enhanceClassName() {
+ return "com.weibo.api.motan.rpc.AbstractProvider";
+ }
+
+ @Override
+ protected MethodMatcher[] getInstanceMethodsMatchers() {
+ return new MethodMatcher[] {new SimpleMethodMatcher("call")};
+ }
+
+ @Override
+ protected String getInstanceMethodsInterceptor() {
+ return "com.a.eye.skywalking.plugin.motan.MotanServerInterceptor";
+ }
+}
diff --git a/skywalking-collector/skywalking-sdk-plugin/motan-plugin/src/main/resources/skywalking-plugin.def b/skywalking-collector/skywalking-sdk-plugin/motan-plugin/src/main/resources/skywalking-plugin.def
new file mode 100644
index 000000000..e70bf5478
--- /dev/null
+++ b/skywalking-collector/skywalking-sdk-plugin/motan-plugin/src/main/resources/skywalking-plugin.def
@@ -0,0 +1,2 @@
+com.a.eye.skywalking.plugin.motan.define.MotanClientDefine
+com.a.eye.skywalking.plugin.motan.define.MotanServerDefine
diff --git a/skywalking-collector/skywalking-sdk-plugin/motan-plugin/src/test/java/com/a/eye/skywalking/plugin/motan/Client.java b/skywalking-collector/skywalking-sdk-plugin/motan-plugin/src/test/java/com/a/eye/skywalking/plugin/motan/Client.java
new file mode 100644
index 000000000..d4e881e28
--- /dev/null
+++ b/skywalking-collector/skywalking-sdk-plugin/motan-plugin/src/test/java/com/a/eye/skywalking/plugin/motan/Client.java
@@ -0,0 +1,30 @@
+package com.a.eye.skywalking.plugin.motan;
+
+import com.a.eye.skywalking.plugin.PluginException;
+import com.a.eye.skywalking.plugin.TracingBootstrap;
+import com.a.eye.skywalking.testframework.api.RequestSpanAssert;
+import org.junit.Test;
+import org.springframework.context.ApplicationContext;
+import org.springframework.context.support.ClassPathXmlApplicationContext;
+
+import java.lang.reflect.InvocationTargetException;
+
+/**
+ * Created by xin on 16/9/27.
+ */
+public class Client {
+ @Test
+ public void test()
+ throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, IllegalAccessException,
+ PluginException {
+ TracingBootstrap.main(new String[] {Client.class.getName()});
+ }
+
+ public static void main(String[] args) throws InterruptedException {
+ ApplicationContext ctx = new ClassPathXmlApplicationContext("classpath:motan_client.xml");
+ FooService service = (FooService) ctx.getBean("remoteService");
+ System.out.println(service.hello("motan", "1"));
+ RequestSpanAssert
+ .assertEquals(new String[][] {{"0", "motan://localhost:8002/com.a.eye.skywalking.plugin.motan.FooService.hello(java.lang.String,java.lang.String)?group=default_rpc", ""}});
+ }
+}
diff --git a/skywalking-collector/skywalking-sdk-plugin/motan-plugin/src/test/java/com/a/eye/skywalking/plugin/motan/FooService.java b/skywalking-collector/skywalking-sdk-plugin/motan-plugin/src/test/java/com/a/eye/skywalking/plugin/motan/FooService.java
new file mode 100644
index 000000000..e4717bef5
--- /dev/null
+++ b/skywalking-collector/skywalking-sdk-plugin/motan-plugin/src/test/java/com/a/eye/skywalking/plugin/motan/FooService.java
@@ -0,0 +1,5 @@
+package com.a.eye.skywalking.plugin.motan;
+
+public interface FooService {
+ public String hello(String name, String value);
+}
diff --git a/skywalking-collector/skywalking-sdk-plugin/motan-plugin/src/test/java/com/a/eye/skywalking/plugin/motan/FooServiceImpl.java b/skywalking-collector/skywalking-sdk-plugin/motan-plugin/src/test/java/com/a/eye/skywalking/plugin/motan/FooServiceImpl.java
new file mode 100644
index 000000000..194bdfbd0
--- /dev/null
+++ b/skywalking-collector/skywalking-sdk-plugin/motan-plugin/src/test/java/com/a/eye/skywalking/plugin/motan/FooServiceImpl.java
@@ -0,0 +1,12 @@
+package com.a.eye.skywalking.plugin.motan;
+
+/**
+ * Created by xin on 16/9/27.
+ */
+public class FooServiceImpl implements FooService {
+
+ public String hello(String name, String value) {
+ System.out.println(name + " invoked rpc service");
+ return "hello " + name + " " + value;
+ }
+}
diff --git a/skywalking-collector/skywalking-sdk-plugin/motan-plugin/src/test/java/com/a/eye/skywalking/plugin/motan/Server.java b/skywalking-collector/skywalking-sdk-plugin/motan-plugin/src/test/java/com/a/eye/skywalking/plugin/motan/Server.java
new file mode 100644
index 000000000..50bc0e8a1
--- /dev/null
+++ b/skywalking-collector/skywalking-sdk-plugin/motan-plugin/src/test/java/com/a/eye/skywalking/plugin/motan/Server.java
@@ -0,0 +1,27 @@
+package com.a.eye.skywalking.plugin.motan;
+
+import com.a.eye.skywalking.plugin.PluginException;
+import com.a.eye.skywalking.plugin.TracingBootstrap;
+import org.junit.Test;
+import org.springframework.context.ApplicationContext;
+import org.springframework.context.support.ClassPathXmlApplicationContext;
+
+import java.lang.reflect.InvocationTargetException;
+
+public class Server {
+ @Test
+ public void test()
+ throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, IllegalAccessException,
+ PluginException {
+ TracingBootstrap.main(new String[] {Server.class.getName()});
+ }
+
+ public static void main(String[] args) throws InterruptedException {
+ ApplicationContext applicationContext = new ClassPathXmlApplicationContext("classpath:motan_server.xml");
+ System.out.println("server start...");
+
+ while (true) {
+ Thread.sleep(100000L);
+ }
+ }
+}
diff --git a/skywalking-collector/skywalking-sdk-plugin/motan-plugin/src/test/resources/motan_client.xml b/skywalking-collector/skywalking-sdk-plugin/motan-plugin/src/test/resources/motan_client.xml
new file mode 100644
index 000000000..171756cbb
--- /dev/null
+++ b/skywalking-collector/skywalking-sdk-plugin/motan-plugin/src/test/resources/motan_client.xml
@@ -0,0 +1,11 @@
+
+