增加Skywalking的Spring埋点和测试类
This commit is contained in:
parent
d089c475c9
commit
64d66eb3c2
|
|
@ -7,6 +7,7 @@
|
|||
<version>1.0-SNAPSHOT</version>
|
||||
<modules>
|
||||
<module>../skywalking-api/skywalking-sdk-plugin</module>
|
||||
<module>spring-plugin</module>
|
||||
</modules>
|
||||
<packaging>pom</packaging>
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,4 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<parent>
|
||||
<artifactId>skywalking-sdk-plugin</artifactId>
|
||||
|
|
@ -10,6 +8,55 @@
|
|||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<artifactId>spring-plugin</artifactId>
|
||||
<packaging>jar</packaging>
|
||||
|
||||
<name>spring-plugin</name>
|
||||
<url>http://maven.apache.org</url>
|
||||
|
||||
</project>
|
||||
<properties>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>junit</groupId>
|
||||
<artifactId>junit</artifactId>
|
||||
<version>3.8.1</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-beans</artifactId>
|
||||
<version>3.2.0.RELEASE</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-context</artifactId>
|
||||
<version>3.2.0.RELEASE</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-aop</artifactId>
|
||||
<version>3.2.0.RELEASE</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.aspectj</groupId>
|
||||
<artifactId>aspectjweaver</artifactId>
|
||||
<version>1.8.7</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.javassist</groupId>
|
||||
<artifactId>javassist</artifactId>
|
||||
<version>3.20.0-GA</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.ai.cloud</groupId>
|
||||
<artifactId>skywalking-api</artifactId>
|
||||
<version>1.0-SNAPSHOT</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</project>
|
||||
|
|
|
|||
|
|
@ -1,7 +0,0 @@
|
|||
package com.ai.cloud.skywalking.plugin.spring;
|
||||
|
||||
/**
|
||||
* Created by astraea on 2015/11/9.
|
||||
*/
|
||||
public class SpringBuriedPoint {
|
||||
}
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
package com.ai.cloud.skywalking.plugin.spring;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
@Target({ElementType.METHOD})
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
public @interface Tracing {
|
||||
}
|
||||
|
|
@ -0,0 +1,175 @@
|
|||
package com.ai.cloud.skywalking.plugin.spring;
|
||||
|
||||
import com.ai.cloud.skywalking.buriedpoint.LocalBuriedPointSender;
|
||||
import com.ai.cloud.skywalking.model.SendData;
|
||||
import javassist.*;
|
||||
import org.springframework.beans.BeansException;
|
||||
import org.springframework.beans.factory.config.BeanPostProcessor;
|
||||
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.ThreadLocalRandom;
|
||||
|
||||
public class TracingEnhanceProcessor implements BeanPostProcessor {
|
||||
|
||||
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
|
||||
List<Method> methods = new ArrayList<Method>();
|
||||
for (Method method : bean.getClass().getMethods()) {
|
||||
if (method.isAnnotationPresent(Tracing.class)) {
|
||||
methods.add(method);
|
||||
}
|
||||
}
|
||||
if (methods.size() > 0) {
|
||||
try {
|
||||
ClassPool mPool = new ClassPool(true);
|
||||
//创建代理类
|
||||
CtClass mCtc = createProxyClass(bean, mPool);
|
||||
//代理类继承所有的被代理的接口
|
||||
inheritanceAllInterfaces(bean, mPool, mCtc);
|
||||
//
|
||||
mCtc.setSuperclass(mPool.get(bean.getClass().getName()));
|
||||
//添加字段
|
||||
mCtc.addField(CtField.make("private " + LocalBuriedPointSender.class.getName() + " buriedPoint;", mCtc));
|
||||
mCtc.addField(CtField.make("private " + bean.getClass().getName() + " realBean;", mCtc));
|
||||
// 校验方法
|
||||
for (Method method : methods) {
|
||||
// 生成方法头
|
||||
StringBuilder result = new StringBuilder();
|
||||
result.append(generateMethodHead(method));
|
||||
// 生成方法参数
|
||||
result.append(generateMethodParameter(method));
|
||||
// 生成抛出异常
|
||||
result.append(generateException(method));
|
||||
// 生成方法体
|
||||
result.append(generateMethodBody(bean, method));
|
||||
// TODO 注解
|
||||
// TODO 参数注解
|
||||
mCtc.addMethod(CtMethod.make(result.toString(), mCtc));
|
||||
}
|
||||
mCtc.addConstructor(CtNewConstructor.make("public " + bean.getClass().getSimpleName() + "Proxy(" + LocalBuriedPointSender.class
|
||||
.getName() + " buriedPoint, " + bean.getClass().getName() + " realBean){" +
|
||||
"this.buriedPoint = buriedPoint;this.realBean = realBean;}", mCtc));
|
||||
mCtc.addConstructor(CtNewConstructor.defaultConstructor(mCtc));
|
||||
Class classes = mCtc.toClass();
|
||||
Constructor constructor = classes.getConstructor(LocalBuriedPointSender.class, bean.getClass());
|
||||
return constructor.newInstance(new LocalBuriedPointSender(), bean);
|
||||
} catch (CannotCompileException e) {
|
||||
e.printStackTrace();
|
||||
} catch (InstantiationException e) {
|
||||
e.printStackTrace();
|
||||
} catch (IllegalAccessException e) {
|
||||
e.printStackTrace();
|
||||
} catch (NoSuchMethodException e) {
|
||||
e.printStackTrace();
|
||||
} catch (InvocationTargetException e) {
|
||||
e.printStackTrace();
|
||||
} catch (NotFoundException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
return bean;
|
||||
}
|
||||
|
||||
private String generateMethodBody(Object bean, Method method) {
|
||||
StringBuilder result = new StringBuilder();
|
||||
result.append("{");
|
||||
result.append(" try{ this.buriedPoint.beforeSend");
|
||||
result.append(generateBeforeSendParamter(bean, method));
|
||||
if (!"void".equals(method.getReturnType().getSimpleName())) {
|
||||
result.append(" return ");
|
||||
}
|
||||
result.append("this.realBean." + method.getName());
|
||||
result.append(generateMethodInvokeParameters(method));
|
||||
result.append("}catch(Throwable e){");
|
||||
result.append(" this.buriedPoint.handleException(e);");
|
||||
result.append(" throw e;");
|
||||
result.append("}finally{");
|
||||
result.append(generateAfterTracing());
|
||||
result.append("}}");
|
||||
return result.toString();
|
||||
}
|
||||
|
||||
private String generateBeforeSendParamter(Object bean, Method method) {
|
||||
StringBuilder builder = new StringBuilder("(" + SendData.class.getName() + ".newBuilder().viewPoint(\""
|
||||
+ bean.getClass().getName() + "." + method.getName());
|
||||
builder.append("(");
|
||||
for (Class param : method.getParameterTypes()) {
|
||||
builder.append(param.getSimpleName() + ",");
|
||||
}
|
||||
if (method.getGenericParameterTypes().length > 0) {
|
||||
builder = builder.delete(builder.length() - 1, builder.length());
|
||||
}
|
||||
builder.append(")");
|
||||
builder.append("\").build());");
|
||||
return builder.toString();
|
||||
}
|
||||
|
||||
private String generateMethodInvokeParameters(Method method) {
|
||||
StringBuilder result = new StringBuilder();
|
||||
int index;
|
||||
result.append("(");
|
||||
index = 0;
|
||||
for (Class parameter : method.getParameterTypes()) {
|
||||
result.append(parameter.getSimpleName().toLowerCase() + "$" + (index++) + ",");
|
||||
}
|
||||
if (method.getParameterTypes().length > 0) {
|
||||
result = result.delete(result.length() - 1, result.length());
|
||||
}
|
||||
result.append(");");
|
||||
return result.toString();
|
||||
}
|
||||
|
||||
private String generateAfterTracing() {
|
||||
return " this.buriedPoint.afterSend();";
|
||||
}
|
||||
|
||||
private String generateException(Method method) {
|
||||
StringBuilder resultB = new StringBuilder(" throws ");
|
||||
for (Class exceptionClasses : method.getExceptionTypes()) {
|
||||
resultB.append(exceptionClasses.getName() + ",");
|
||||
}
|
||||
if (method.getExceptionTypes().length > 0) {
|
||||
resultB.delete(resultB.length() - 1, resultB.length());
|
||||
} else {
|
||||
resultB = new StringBuilder();
|
||||
}
|
||||
return resultB.toString();
|
||||
}
|
||||
|
||||
private String generateMethodParameter(Method method) {
|
||||
StringBuilder result = new StringBuilder();
|
||||
result.append("(");
|
||||
int index = 0;
|
||||
for (Class param : method.getParameterTypes()) {
|
||||
result.append(param.getSimpleName() + " " + param.getSimpleName().
|
||||
toLowerCase() + "$" + (index++) + ",");
|
||||
}
|
||||
if (method.getGenericParameterTypes().length > 0) {
|
||||
result = result.delete(result.length() - 1, result.length());
|
||||
}
|
||||
result.append(")");
|
||||
return result.toString();
|
||||
}
|
||||
|
||||
private String generateMethodHead(Method method) {
|
||||
return "public " + method.getReturnType().getSimpleName() + " " + method.getName();
|
||||
}
|
||||
|
||||
private CtClass createProxyClass(Object bean, ClassPool mPool) {
|
||||
return mPool.makeClass(bean.getClass().getSimpleName() + "Proxy$" + ThreadLocalRandom.current().nextInt(100));
|
||||
}
|
||||
|
||||
private void inheritanceAllInterfaces(Object bean, ClassPool mPool, CtClass mCtc) throws NotFoundException {
|
||||
for (Class classes : bean.getClass().getInterfaces()) {
|
||||
mCtc.addInterface(mPool.get(classes.getClass().getName()));
|
||||
}
|
||||
}
|
||||
|
||||
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
|
||||
return bean;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
package com.ai.cloud.skywalking.plugin.spring.aspect;
|
||||
|
||||
public class AspectBean {
|
||||
public void before() {
|
||||
System.out.println("before aspect");
|
||||
}
|
||||
|
||||
public void after() {
|
||||
System.out.println("after aspect");
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,13 @@
|
|||
package com.ai.cloud.skywalking.plugin.spring.aspect;
|
||||
|
||||
import org.springframework.context.support.ClassPathXmlApplicationContext;
|
||||
|
||||
public class TestAspect {
|
||||
|
||||
public static void main(String[] args) {
|
||||
ClassPathXmlApplicationContext classPathXmlApplicationContext =
|
||||
new ClassPathXmlApplicationContext("classpath*:springConfig-aspect.xml");
|
||||
TracingAspectBean testBuriedPointBean = classPathXmlApplicationContext.getBean(TracingAspectBean.class);
|
||||
testBuriedPointBean.doBusiness();
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
package com.ai.cloud.skywalking.plugin.spring.aspect;
|
||||
|
||||
import com.ai.cloud.skywalking.plugin.spring.Tracing;
|
||||
|
||||
public class TracingAspectBean {
|
||||
|
||||
@Tracing
|
||||
public String doBusiness() {
|
||||
System.out.println("do business");
|
||||
return "Hello World";
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,13 @@
|
|||
package com.ai.cloud.skywalking.plugin.spring.common;
|
||||
|
||||
import org.springframework.context.support.ClassPathXmlApplicationContext;
|
||||
|
||||
public class TestBuriedPoint {
|
||||
|
||||
public static void main(String[] args) {
|
||||
ClassPathXmlApplicationContext classPathXmlApplicationContext = new ClassPathXmlApplicationContext("classpath*:springConfig-common.xml");
|
||||
TestBuriedPointBean testBuriedPointBean = classPathXmlApplicationContext.getBean(TestBuriedPointBean.class);
|
||||
testBuriedPointBean.sayTest();
|
||||
System.out.println(testBuriedPointBean.addStr(1));
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,27 @@
|
|||
package com.ai.cloud.skywalking.plugin.spring.common;
|
||||
|
||||
import com.ai.cloud.skywalking.plugin.spring.Tracing;
|
||||
|
||||
|
||||
public class TestBuriedPointBean {
|
||||
@Tracing
|
||||
public void sayTest() throws RuntimeException, IllegalStateException {
|
||||
System.out.println("say Test");
|
||||
}
|
||||
|
||||
@Tracing
|
||||
public static void sayTest1() {
|
||||
System.out.println("xx");
|
||||
}
|
||||
|
||||
@Tracing
|
||||
public String addStr(int a, String c) {
|
||||
throw new RuntimeException("aa");
|
||||
}
|
||||
|
||||
@Tracing
|
||||
public String addStr(int a) {
|
||||
throw new RuntimeException("aa");
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,24 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<beans
|
||||
xmlns="http://www.springframework.org/schema/beans"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns:aop="http://www.springframework.org/schema/aop"
|
||||
xsi:schemaLocation="http://www.springframework.org/schema/beans
|
||||
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
|
||||
http://www.springframework.org/schema/aop
|
||||
http://www.springframework.org/schema/aop/spring-aop.xsd">
|
||||
|
||||
<bean id="postProcess1"
|
||||
class="com.ai.cloud.skywalking.plugin.spring.TracingEnhanceProcessor">
|
||||
</bean>
|
||||
<bean id="aspectBean" class="com.ai.cloud.skywalking.plugin.spring.aspect.AspectBean"/>
|
||||
<bean id="testBuriedPointAspect" class="com.ai.cloud.skywalking.plugin.spring.aspect.TracingAspectBean"/>
|
||||
<aop:config>
|
||||
<aop:aspect ref="aspectBean">
|
||||
<aop:pointcut id="testPointCut"
|
||||
expression="execution(* com.ai.cloud.skywalking.plugin.spring.aspect..*(..))"/>
|
||||
<aop:before method="before" pointcut-ref="testPointCut"/>
|
||||
<aop:after method="after" pointcut-ref="testPointCut"/>
|
||||
</aop:aspect>
|
||||
</aop:config>
|
||||
</beans>
|
||||
|
|
@ -0,0 +1,18 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<beans
|
||||
xmlns="http://www.springframework.org/schema/beans"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns:aop="http://www.springframework.org/schema/aop"
|
||||
xsi:schemaLocation="http://www.springframework.org/schema/beans
|
||||
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
|
||||
http://www.springframework.org/schema/aop
|
||||
http://www.springframework.org/schema/aop/spring-aop.xsd">
|
||||
|
||||
<bean id="postProcess1"
|
||||
class="com.ai.cloud.skywalking.plugin.spring.TracingEnhanceProcessor">
|
||||
</bean>
|
||||
|
||||
<bean id="testBean" class="com.ai.cloud.skywalking.plugin.spring.common.TestBuriedPointBean"/>
|
||||
|
||||
<aop:aspectj-autoproxy/>
|
||||
</beans>
|
||||
Loading…
Reference in New Issue