From 852aec981d37dedd6930b901bbabce1c448b0a48 Mon Sep 17 00:00:00 2001 From: wusheng Date: Thu, 10 Mar 2016 16:39:14 +0800 Subject: [PATCH 1/3] =?UTF-8?q?1.=E5=A2=9E=E5=8A=A0=E6=9E=84=E9=80=A0?= =?UTF-8?q?=E5=87=BD=E6=95=B0=E6=8B=A6=E6=88=AA=E7=9A=84=E6=B5=8B=E8=AF=95?= =?UTF-8?q?=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../bytebuddy/ConstructorInterceptor.java | 16 +++++ ...nterceptor.java => MethodInterceptor.java} | 7 ++- .../test/ai/cloud/bytebuddy/SimulateMain.java | 62 ++++++++++--------- .../test/ai/cloud/bytebuddy/TestClass.java | 9 +++ 4 files changed, 62 insertions(+), 32 deletions(-) create mode 100644 skywalking-api/src/test/java/test/ai/cloud/bytebuddy/ConstructorInterceptor.java rename skywalking-api/src/test/java/test/ai/cloud/bytebuddy/{Interceptor.java => MethodInterceptor.java} (63%) diff --git a/skywalking-api/src/test/java/test/ai/cloud/bytebuddy/ConstructorInterceptor.java b/skywalking-api/src/test/java/test/ai/cloud/bytebuddy/ConstructorInterceptor.java new file mode 100644 index 000000000..2fe37919e --- /dev/null +++ b/skywalking-api/src/test/java/test/ai/cloud/bytebuddy/ConstructorInterceptor.java @@ -0,0 +1,16 @@ +package test.ai.cloud.bytebuddy; + +import net.bytebuddy.implementation.bind.annotation.AllArguments; +import net.bytebuddy.implementation.bind.annotation.RuntimeType; +import net.bytebuddy.implementation.bind.annotation.This; + +public class ConstructorInterceptor { + @RuntimeType + public void intercept(@AllArguments Object[] allArguments) { + System.out + .println("ConstructorInterceptor size:" + allArguments.length); + if(allArguments.length > 0){ + System.out.println("ConstructorInterceptor param[0]=" + allArguments[0]); + } + } +} diff --git a/skywalking-api/src/test/java/test/ai/cloud/bytebuddy/Interceptor.java b/skywalking-api/src/test/java/test/ai/cloud/bytebuddy/MethodInterceptor.java similarity index 63% rename from skywalking-api/src/test/java/test/ai/cloud/bytebuddy/Interceptor.java rename to skywalking-api/src/test/java/test/ai/cloud/bytebuddy/MethodInterceptor.java index 7180f2b1c..332971af8 100644 --- a/skywalking-api/src/test/java/test/ai/cloud/bytebuddy/Interceptor.java +++ b/skywalking-api/src/test/java/test/ai/cloud/bytebuddy/MethodInterceptor.java @@ -7,12 +7,13 @@ import net.bytebuddy.implementation.bind.annotation.AllArguments; import net.bytebuddy.implementation.bind.annotation.Origin; import net.bytebuddy.implementation.bind.annotation.RuntimeType; import net.bytebuddy.implementation.bind.annotation.SuperCall; +import net.bytebuddy.implementation.bind.annotation.This; -public class Interceptor{ +public class MethodInterceptor{ @RuntimeType - public Object intercept(@AllArguments Object[] allArguments, @Origin Method method, @SuperCall Callable zuper){ + public Object intercept(@This Object obj, @AllArguments Object[] allArguments, @Origin Method method, @SuperCall Callable zuper){ try { - return "intercept_" + zuper.call(); + return method.getName() + ":intercept_" + zuper.call(); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); diff --git a/skywalking-api/src/test/java/test/ai/cloud/bytebuddy/SimulateMain.java b/skywalking-api/src/test/java/test/ai/cloud/bytebuddy/SimulateMain.java index 453c53b6f..f46e1eeff 100644 --- a/skywalking-api/src/test/java/test/ai/cloud/bytebuddy/SimulateMain.java +++ b/skywalking-api/src/test/java/test/ai/cloud/bytebuddy/SimulateMain.java @@ -1,49 +1,53 @@ package test.ai.cloud.bytebuddy; -import static net.bytebuddy.matcher.ElementMatchers.named; +import static net.bytebuddy.matcher.ElementMatchers.isConstructor; +import static net.bytebuddy.matcher.ElementMatchers.isMethod; import net.bytebuddy.ByteBuddy; import net.bytebuddy.dynamic.ClassFileLocator; import net.bytebuddy.dynamic.loading.ClassLoadingStrategy; import net.bytebuddy.implementation.MethodDelegation; +import net.bytebuddy.implementation.SuperMethodCall; import net.bytebuddy.pool.TypePool; public class SimulateMain { public static void main(String[] args) throws NoSuchFieldException, SecurityException, InstantiationException, IllegalAccessException { TypePool typePool = TypePool.Default.ofClassPath(); - - Object newClazzObj = new ByteBuddy() - .redefine( - typePool.describe( - "test.ai.cloud.bytebuddy.TestClass") - .resolve(), - ClassFileLocator.ForClassLoader.ofClassPath()) - .name("test.ai.cloud.bytebuddy.TestClass$$Origin") - .make() - .load(ClassLoader.getSystemClassLoader(), - ClassLoadingStrategy.Default.INJECTION).getLoaded().newInstance(); - TestClass t22 = (TestClass)(new ByteBuddy() - .subclass(newClazzObj.getClass()) - .method(named("testA")) - .intercept(MethodDelegation.to(new Interceptor())) + Class newClazz = new ByteBuddy() + .redefine( + typePool.describe("test.ai.cloud.bytebuddy.TestClass") + .resolve(), + ClassFileLocator.ForClassLoader.ofClassPath()) + .name("test.ai.cloud.bytebuddy.TestClass$$Origin") + .make() + .load(ClassLoader.getSystemClassLoader(), + ClassLoadingStrategy.Default.INJECTION).getLoaded(); + + TestClass t22 = (TestClass) (new ByteBuddy() + .subclass(newClazz) + .method(isMethod()) + .intercept(MethodDelegation.to(new MethodInterceptor())) + .constructor(isConstructor()) + .intercept(MethodDelegation.to(new ConstructorInterceptor()).andThen(SuperMethodCall.INSTANCE)) .name("test.ai.cloud.bytebuddy.TestClass") .make() .load(ClassLoader.getSystemClassLoader(), - ClassLoadingStrategy.Default.INJECTION).getLoaded().newInstance()); + ClassLoadingStrategy.Default.INJECTION).getLoaded() + .newInstance()); - //System.out.println(t22.testA("1")); - - TestClass t = new TestClass(); + // System.out.println(t22.testA("1")); + TestClass t = new TestClass("abc"); System.out.println(t.testA("1")); - - TestClass t2 = null; - try { - t2 = (TestClass)Class.forName("test.ai.cloud.bytebuddy.TestClass").newInstance(); - } catch (ClassNotFoundException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } - System.out.println(t2.testA("1")); + +// TestClass t2 = null; +// try { +// t2 = (TestClass) Class.forName("test.ai.cloud.bytebuddy.TestClass") +// .newInstance(); +// } catch (ClassNotFoundException e) { +// // TODO Auto-generated catch block +// e.printStackTrace(); +// } +// System.out.println(t2.testA("1")); } } diff --git a/skywalking-api/src/test/java/test/ai/cloud/bytebuddy/TestClass.java b/skywalking-api/src/test/java/test/ai/cloud/bytebuddy/TestClass.java index 4a2129bad..7740bc3b1 100644 --- a/skywalking-api/src/test/java/test/ai/cloud/bytebuddy/TestClass.java +++ b/skywalking-api/src/test/java/test/ai/cloud/bytebuddy/TestClass.java @@ -1,6 +1,15 @@ package test.ai.cloud.bytebuddy; public class TestClass { + public TestClass(){ + //System.out.println("init:" + this.getClass().getName()); + } + + public TestClass(String tmp){ + //System.out.println("init:" + this.getClass().getName()); + } + + public String testA(String aa){ // throw new RuntimeException("adfasdfas"); return "TestClass.testA"; From 47fde7ebb843f153ed1c45c41f332f6d5c6f5b1d Mon Sep 17 00:00:00 2001 From: wusheng Date: Fri, 11 Mar 2016 16:28:11 +0800 Subject: [PATCH 2/3] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E9=83=A8=E5=88=86?= =?UTF-8?q?=E4=BB=A3=E7=A0=81=EF=BC=8C=E6=8F=90=E4=BE=9B=E6=96=B0=E7=9A=84?= =?UTF-8?q?=E5=BA=94=E7=94=A8=E7=A8=8B=E5=BA=8F=E5=85=A5=E5=8F=A3=EF=BC=8C?= =?UTF-8?q?=E7=94=A8=E4=BA=8E=E5=A2=9E=E5=BC=BA=E7=B1=BB=E5=AE=9E=E7=8E=B0?= =?UTF-8?q?=E3=80=82#36?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../skywalking/conf/ConfigInitializer.java | 20 +++---- .../skywalking/plugin/PluginBootstrap.java | 40 ++++++++++++++ .../ai/cloud/skywalking/plugin/PluginCfg.java | 36 +++++++++++++ .../plugin/PluginResourcesResolver.java | 49 +++++++++++++++++ .../skywalking/plugin/TracingBootstrap.java | 33 ++++++++++++ .../interceptor/EnhanceClazz4Interceptor.java | 52 +++++++++++++++++++ .../selfexamination/SDKHealthCollector.java | 2 +- .../plugin/PluginResourceResoverTest.java | 14 +++++ skywalking-api/src/test/resources/log4j2.xml | 13 +++++ .../resources/skywalking-plugin.properties | 0 10 files changed, 249 insertions(+), 10 deletions(-) create mode 100644 skywalking-api/src/main/java/com/ai/cloud/skywalking/plugin/PluginBootstrap.java create mode 100644 skywalking-api/src/main/java/com/ai/cloud/skywalking/plugin/PluginCfg.java create mode 100644 skywalking-api/src/main/java/com/ai/cloud/skywalking/plugin/PluginResourcesResolver.java create mode 100644 skywalking-api/src/main/java/com/ai/cloud/skywalking/plugin/TracingBootstrap.java create mode 100644 skywalking-api/src/main/java/com/ai/cloud/skywalking/plugin/interceptor/EnhanceClazz4Interceptor.java create mode 100644 skywalking-api/src/test/java/test/ai/cloud/plugin/PluginResourceResoverTest.java create mode 100644 skywalking-api/src/test/resources/log4j2.xml create mode 100644 skywalking-api/src/test/resources/skywalking-plugin.properties diff --git a/skywalking-api/src/main/java/com/ai/cloud/skywalking/conf/ConfigInitializer.java b/skywalking-api/src/main/java/com/ai/cloud/skywalking/conf/ConfigInitializer.java index 116cb1645..18f5bc61e 100644 --- a/skywalking-api/src/main/java/com/ai/cloud/skywalking/conf/ConfigInitializer.java +++ b/skywalking-api/src/main/java/com/ai/cloud/skywalking/conf/ConfigInitializer.java @@ -1,38 +1,40 @@ package com.ai.cloud.skywalking.conf; +import static com.ai.cloud.skywalking.conf.Config.SkyWalking.AUTH_OVERRIDE; +import static com.ai.cloud.skywalking.conf.Config.SkyWalking.AUTH_SYSTEM_ENV_NAME; + import java.io.IOException; import java.io.InputStream; import java.lang.reflect.Field; import java.lang.reflect.Modifier; import java.util.LinkedList; import java.util.Properties; -import java.util.logging.Level; -import java.util.logging.Logger; -import static com.ai.cloud.skywalking.conf.Config.SkyWalking.*; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; public class ConfigInitializer { - private static Logger logger = Logger.getLogger(ConfigInitializer.class.getName()); + private static Logger logger = LogManager.getLogger(ConfigInitializer.class); public static void initialize() { InputStream inputStream = ConfigInitializer.class.getResourceAsStream("/sky-walking.auth"); if (inputStream == null) { - logger.log(Level.ALL, "No provider sky-walking certification documents, sky-walking api auto shutdown."); + logger.info("No provider sky-walking certification documents, sky-walking api auto shutdown."); } else { try { Properties properties = new Properties(); properties.load(inputStream); initNextLevel(properties, Config.class, new ConfigDesc()); AuthDesc.isAuth = Boolean.valueOf(System.getenv(AUTH_SYSTEM_ENV_NAME)); - logger.log(Level.ALL, "sky-walking auth check : " + AuthDesc.isAuth); + logger.info("sky-walking auth check : " + AuthDesc.isAuth); if(!AuthDesc.isAuth && AUTH_OVERRIDE){ AuthDesc.isAuth = AUTH_OVERRIDE; - logger.log(Level.ALL, "sky-walking auth override: " + AuthDesc.isAuth); + logger.info("sky-walking auth override: " + AuthDesc.isAuth); } } catch (IllegalAccessException e) { - logger.log(Level.ALL, "Parsing certification file failed, sky-walking api auto shutdown."); + logger.error("Parsing certification file failed, sky-walking api auto shutdown.", e); } catch (IOException e) { - logger.log(Level.ALL, "Failed to read the certification file, sky-walking api auto shutdown."); + logger.error("Failed to read the certification file, sky-walking api auto shutdown.", e); } } } diff --git a/skywalking-api/src/main/java/com/ai/cloud/skywalking/plugin/PluginBootstrap.java b/skywalking-api/src/main/java/com/ai/cloud/skywalking/plugin/PluginBootstrap.java new file mode 100644 index 000000000..ffcda0f24 --- /dev/null +++ b/skywalking-api/src/main/java/com/ai/cloud/skywalking/plugin/PluginBootstrap.java @@ -0,0 +1,40 @@ +package com.ai.cloud.skywalking.plugin; + +import java.net.URL; +import java.util.Enumeration; + +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; + +import com.ai.cloud.skywalking.conf.AuthDesc; +import com.ai.cloud.skywalking.plugin.interceptor.EnhanceClazz4Interceptor; + +public class PluginBootstrap { + private static Logger logger = LogManager.getLogger(PluginBootstrap.class); + + public void start() { + if (!AuthDesc.isAuth()) { + return; + } + + PluginResourcesResolver resolver = new PluginResourcesResolver(); + Enumeration resources = resolver.getResources(); + + if (resources == null || !resources.hasMoreElements()) { + logger.info("no plugin files (skywalking-plugin.properties) found, continue to start application."); + return; + } + + while (resources.hasMoreElements()) { + URL pluginUrl = resources.nextElement(); + try { + PluginCfg.CFG.load(pluginUrl.openStream()); + } catch (Throwable t) { + logger.error("plugin [{}] init failure.", pluginUrl, t); + } + } + + EnhanceClazz4Interceptor enhanceClazz4Interceptor = new EnhanceClazz4Interceptor(); + enhanceClazz4Interceptor.enhance(); + } +} diff --git a/skywalking-api/src/main/java/com/ai/cloud/skywalking/plugin/PluginCfg.java b/skywalking-api/src/main/java/com/ai/cloud/skywalking/plugin/PluginCfg.java new file mode 100644 index 000000000..229d6dbfb --- /dev/null +++ b/skywalking-api/src/main/java/com/ai/cloud/skywalking/plugin/PluginCfg.java @@ -0,0 +1,36 @@ +package com.ai.cloud.skywalking.plugin; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.util.HashSet; +import java.util.Set; + +import com.ai.cloud.skywalking.util.StringUtil; + +public class PluginCfg { + public final static PluginCfg CFG = new PluginCfg(); + + private Set interceptorClassList = new HashSet(); + + private PluginCfg(){} + + void load(InputStream input) throws IOException{ + try{ + BufferedReader reader = new BufferedReader(new InputStreamReader(input)); + String nhanceOriginClassName = null; + while((nhanceOriginClassName = reader.readLine()) != null){ + if(!StringUtil.isEmpty(nhanceOriginClassName)){ + interceptorClassList.add(nhanceOriginClassName.trim()); + } + } + }finally{ + input.close(); + } + } + + public Set getInterceptorClassList(){ + return interceptorClassList; + } +} diff --git a/skywalking-api/src/main/java/com/ai/cloud/skywalking/plugin/PluginResourcesResolver.java b/skywalking-api/src/main/java/com/ai/cloud/skywalking/plugin/PluginResourcesResolver.java new file mode 100644 index 000000000..c311cd689 --- /dev/null +++ b/skywalking-api/src/main/java/com/ai/cloud/skywalking/plugin/PluginResourcesResolver.java @@ -0,0 +1,49 @@ +package com.ai.cloud.skywalking.plugin; + +import java.io.IOException; +import java.net.URL; +import java.util.Enumeration; + +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; + +public class PluginResourcesResolver { + private static Logger logger = LogManager.getLogger(PluginResourcesResolver.class); + + public Enumeration getResources(){ + Enumeration urls; + try { + urls = getDefaultClassLoader().getResources("skywalking-plugin.properties"); + + if(!urls.hasMoreElements()){ + logger.info("no plugin files (skywalking-plugin.properties) found"); + } + + while(urls.hasMoreElements()){ + URL pluginUrl = urls.nextElement(); + logger.info("find skywalking plugin define in {}", pluginUrl); + } + + return urls; + } catch (IOException e) { + logger.error("read resources failure.", e); + } + return null; + } + + private ClassLoader getDefaultClassLoader() { + ClassLoader cl = null; + try { + cl = Thread.currentThread().getContextClassLoader(); + } + catch (Throwable ex) { + // Cannot access thread context ClassLoader - falling back to system class loader... + } + if (cl == null) { + // No thread context class loader -> use class loader of this class. + cl = PluginResourcesResolver.class.getClassLoader(); + } + return cl; + } + +} diff --git a/skywalking-api/src/main/java/com/ai/cloud/skywalking/plugin/TracingBootstrap.java b/skywalking-api/src/main/java/com/ai/cloud/skywalking/plugin/TracingBootstrap.java new file mode 100644 index 000000000..2d98aa187 --- /dev/null +++ b/skywalking-api/src/main/java/com/ai/cloud/skywalking/plugin/TracingBootstrap.java @@ -0,0 +1,33 @@ +package com.ai.cloud.skywalking.plugin; + +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; + +/** + * 替代应用函数的main函数入口,确保在程序入口处运行
+ * 用于替代-javaagent的另一种模式
+ * + * @author wusheng + * + */ +public class TracingBootstrap { + private static Logger logger = LogManager.getLogger(TracingBootstrap.class); + + private TracingBootstrap() { + } + + public static void main(String[] args) { + if (args.length == 0) { + throw new RuntimeException( + "bootstrap failure. need args[0] to be main class."); + } + + try { + PluginBootstrap bootstrap = new PluginBootstrap(); + bootstrap.start(); + } catch (Throwable t) { + logger.error("PluginBootstrap start failure.", t); + } + + } +} diff --git a/skywalking-api/src/main/java/com/ai/cloud/skywalking/plugin/interceptor/EnhanceClazz4Interceptor.java b/skywalking-api/src/main/java/com/ai/cloud/skywalking/plugin/interceptor/EnhanceClazz4Interceptor.java new file mode 100644 index 000000000..3ede5e498 --- /dev/null +++ b/skywalking-api/src/main/java/com/ai/cloud/skywalking/plugin/interceptor/EnhanceClazz4Interceptor.java @@ -0,0 +1,52 @@ +package com.ai.cloud.skywalking.plugin.interceptor; + +import java.util.Set; + +import net.bytebuddy.ByteBuddy; +import net.bytebuddy.dynamic.ClassFileLocator; +import net.bytebuddy.dynamic.loading.ClassLoadingStrategy; +import net.bytebuddy.pool.TypePool; + +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; + +import com.ai.cloud.skywalking.plugin.PluginCfg; + +public class EnhanceClazz4Interceptor { + private static Logger logger = LogManager + .getLogger(EnhanceClazz4Interceptor.class); + + private TypePool typePool; + + public EnhanceClazz4Interceptor() { + typePool = TypePool.Default.ofClassPath(); + } + + public void enhance() { + Set interceptorClassList = PluginCfg.CFG + .getInterceptorClassList(); + + for (String interceptorClassName : interceptorClassList) { + try { + enhance0(interceptorClassName); + } catch (Throwable t) { + logger.error("enhance class [{}] for intercept failure.", + interceptorClassName, t); + } + } + } + + private void enhance0(String enhanceOriginClassName) { + /** + * add '$$Origin' at the end of be enhanced classname
+ * such as: class com.ai.cloud.TestClass to class com.ai.cloud.TestClass$$Origin + */ + new ByteBuddy() + .redefine(typePool.describe(enhanceOriginClassName).resolve(), + ClassFileLocator.ForClassLoader.ofClassPath()) + .name(enhanceOriginClassName + "$$Origin") + .make() + .load(ClassLoader.getSystemClassLoader(), + ClassLoadingStrategy.Default.INJECTION).getLoaded(); + } +} diff --git a/skywalking-api/src/main/java/com/ai/cloud/skywalking/selfexamination/SDKHealthCollector.java b/skywalking-api/src/main/java/com/ai/cloud/skywalking/selfexamination/SDKHealthCollector.java index d9c6c770f..414e48675 100644 --- a/skywalking-api/src/main/java/com/ai/cloud/skywalking/selfexamination/SDKHealthCollector.java +++ b/skywalking-api/src/main/java/com/ai/cloud/skywalking/selfexamination/SDKHealthCollector.java @@ -12,7 +12,7 @@ import com.ai.cloud.skywalking.conf.Config; import com.ai.cloud.skywalking.util.BuriedPointMachineUtil; public class SDKHealthCollector extends Thread { - private Logger logger = LogManager.getLogger(SDKHealthCollector.class); + private static Logger logger = LogManager.getLogger(SDKHealthCollector.class); private static Map heathReadings = new ConcurrentHashMap(); diff --git a/skywalking-api/src/test/java/test/ai/cloud/plugin/PluginResourceResoverTest.java b/skywalking-api/src/test/java/test/ai/cloud/plugin/PluginResourceResoverTest.java new file mode 100644 index 000000000..10315a55f --- /dev/null +++ b/skywalking-api/src/test/java/test/ai/cloud/plugin/PluginResourceResoverTest.java @@ -0,0 +1,14 @@ +package test.ai.cloud.plugin; + +import java.io.IOException; + +import com.ai.cloud.skywalking.plugin.PluginResourcesResolver; + +public class PluginResourceResoverTest { + + public static void main(String[] args) throws IOException { + PluginResourcesResolver resolver = new PluginResourcesResolver(); + resolver.getResources(); + } + +} diff --git a/skywalking-api/src/test/resources/log4j2.xml b/skywalking-api/src/test/resources/log4j2.xml new file mode 100644 index 000000000..4559d6d69 --- /dev/null +++ b/skywalking-api/src/test/resources/log4j2.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/skywalking-api/src/test/resources/skywalking-plugin.properties b/skywalking-api/src/test/resources/skywalking-plugin.properties new file mode 100644 index 000000000..e69de29bb From d635a4aff651cf900c4881e3350a1f834feb0bce Mon Sep 17 00:00:00 2001 From: wusheng Date: Fri, 11 Mar 2016 17:27:29 +0800 Subject: [PATCH 3/3] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E5=A4=A7=E9=87=8F?= =?UTF-8?q?=E7=9A=84=E5=A4=8D=E6=9D=82=E7=BB=93=E6=9E=84=EF=BC=8C=E7=94=A8?= =?UTF-8?q?=E4=BA=8E=E5=AE=9A=E4=B9=89=E5=AF=B9=E7=B1=BB=E7=9A=84=E6=8B=A6?= =?UTF-8?q?=E6=88=AA=EF=BC=8C=E4=BB=A5=E5=8F=8A=E5=AE=9E=E4=BE=8B=E7=BA=A7?= =?UTF-8?q?=E4=B8=8A=E4=B8=8B=E6=96=87=E5=AD=98=E5=82=A8=E3=80=82#36?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../interceptor/EnhanceClazz4Interceptor.java | 13 ++++++++++++- .../EnhancedClassInstanceContext.java | 18 ++++++++++++++++++ .../plugin/interceptor/IAroundInterceptor.java | 11 +++++++++++ .../IEnhancedClassInstanceContext.java | 12 ++++++++++++ .../plugin/interceptor/InterceptorDefine.java | 9 +++++++++ .../test/ai/cloud/bytebuddy/SimulateMain.java | 5 ++++- 6 files changed, 66 insertions(+), 2 deletions(-) create mode 100644 skywalking-api/src/main/java/com/ai/cloud/skywalking/plugin/interceptor/EnhancedClassInstanceContext.java create mode 100644 skywalking-api/src/main/java/com/ai/cloud/skywalking/plugin/interceptor/IAroundInterceptor.java create mode 100644 skywalking-api/src/main/java/com/ai/cloud/skywalking/plugin/interceptor/IEnhancedClassInstanceContext.java create mode 100644 skywalking-api/src/main/java/com/ai/cloud/skywalking/plugin/interceptor/InterceptorDefine.java diff --git a/skywalking-api/src/main/java/com/ai/cloud/skywalking/plugin/interceptor/EnhanceClazz4Interceptor.java b/skywalking-api/src/main/java/com/ai/cloud/skywalking/plugin/interceptor/EnhanceClazz4Interceptor.java index 3ede5e498..dea537914 100644 --- a/skywalking-api/src/main/java/com/ai/cloud/skywalking/plugin/interceptor/EnhanceClazz4Interceptor.java +++ b/skywalking-api/src/main/java/com/ai/cloud/skywalking/plugin/interceptor/EnhanceClazz4Interceptor.java @@ -36,7 +36,10 @@ public class EnhanceClazz4Interceptor { } } - private void enhance0(String enhanceOriginClassName) { + private void enhance0(String interceptorDefineClassName) throws InstantiationException, IllegalAccessException, ClassNotFoundException { + InterceptorDefine define = (InterceptorDefine)Class.forName(interceptorDefineClassName).newInstance(); + + String enhanceOriginClassName = define.getBeInterceptedClassName(); /** * add '$$Origin' at the end of be enhanced classname
* such as: class com.ai.cloud.TestClass to class com.ai.cloud.TestClass$$Origin @@ -48,5 +51,13 @@ public class EnhanceClazz4Interceptor { .make() .load(ClassLoader.getSystemClassLoader(), ClassLoadingStrategy.Default.INJECTION).getLoaded(); + + /** + * define class as origin class name. and inject to classloader.
+ * new class need:
+ * 1.implement com.ai.cloud.skywalking.plugin.interceptor.IEnhancedClassInstanceContext();
+ * 2.add field '_$EnhancedClassInstanceContext' of type EnhancedClassInstanceContext + * 3.intercept constructor and method if required by interceptorDefineClass + */ } } diff --git a/skywalking-api/src/main/java/com/ai/cloud/skywalking/plugin/interceptor/EnhancedClassInstanceContext.java b/skywalking-api/src/main/java/com/ai/cloud/skywalking/plugin/interceptor/EnhancedClassInstanceContext.java new file mode 100644 index 000000000..f15ceff30 --- /dev/null +++ b/skywalking-api/src/main/java/com/ai/cloud/skywalking/plugin/interceptor/EnhancedClassInstanceContext.java @@ -0,0 +1,18 @@ +package com.ai.cloud.skywalking.plugin.interceptor; + +import java.util.HashMap; +import java.util.Map; + +/** + * 被增强的类实例,需扩展的context属性,用于在不同的方法,或者构造函数间保存实例 + * + * @author wusheng + * + */ +public class EnhancedClassInstanceContext { + public static final String FIELD_NAME = "_$EnhancedClassInstanceContext"; + + private Map context = new HashMap(); + + +} diff --git a/skywalking-api/src/main/java/com/ai/cloud/skywalking/plugin/interceptor/IAroundInterceptor.java b/skywalking-api/src/main/java/com/ai/cloud/skywalking/plugin/interceptor/IAroundInterceptor.java new file mode 100644 index 000000000..861fc4107 --- /dev/null +++ b/skywalking-api/src/main/java/com/ai/cloud/skywalking/plugin/interceptor/IAroundInterceptor.java @@ -0,0 +1,11 @@ +package com.ai.cloud.skywalking.plugin.interceptor; + +public interface IAroundInterceptor { + public void onConstruct(EnhancedClassInstanceContext context); + + public void beforeMethod(EnhancedClassInstanceContext context); + + public void afterMethod(EnhancedClassInstanceContext context); + + +} diff --git a/skywalking-api/src/main/java/com/ai/cloud/skywalking/plugin/interceptor/IEnhancedClassInstanceContext.java b/skywalking-api/src/main/java/com/ai/cloud/skywalking/plugin/interceptor/IEnhancedClassInstanceContext.java new file mode 100644 index 000000000..fa7fccd50 --- /dev/null +++ b/skywalking-api/src/main/java/com/ai/cloud/skywalking/plugin/interceptor/IEnhancedClassInstanceContext.java @@ -0,0 +1,12 @@ +package com.ai.cloud.skywalking.plugin.interceptor; + +/** + * 被增强的类,会实现此接口,用于快速获取实例级属性上下文扩展
+ * @see com.ai.cloud.skywalking.plugin.interceptor.EnhanceClazz4Interceptor.enhance0() + * + * @author wusheng + * + */ +public interface IEnhancedClassInstanceContext { + public EnhancedClassInstanceContext getEnhancedClassInstanceContext(); +} diff --git a/skywalking-api/src/main/java/com/ai/cloud/skywalking/plugin/interceptor/InterceptorDefine.java b/skywalking-api/src/main/java/com/ai/cloud/skywalking/plugin/interceptor/InterceptorDefine.java new file mode 100644 index 000000000..c51010506 --- /dev/null +++ b/skywalking-api/src/main/java/com/ai/cloud/skywalking/plugin/interceptor/InterceptorDefine.java @@ -0,0 +1,9 @@ +package com.ai.cloud.skywalking.plugin.interceptor; + +public interface InterceptorDefine { + public String getBeInterceptedClassName(); + + public String[] getBeInterceptedMethods(); + + public IAroundInterceptor instance(); +} diff --git a/skywalking-api/src/test/java/test/ai/cloud/bytebuddy/SimulateMain.java b/skywalking-api/src/test/java/test/ai/cloud/bytebuddy/SimulateMain.java index f46e1eeff..e2e763ca5 100644 --- a/skywalking-api/src/test/java/test/ai/cloud/bytebuddy/SimulateMain.java +++ b/skywalking-api/src/test/java/test/ai/cloud/bytebuddy/SimulateMain.java @@ -11,7 +11,7 @@ import net.bytebuddy.pool.TypePool; public class SimulateMain { public static void main(String[] args) throws NoSuchFieldException, - SecurityException, InstantiationException, IllegalAccessException { + SecurityException, InstantiationException, IllegalAccessException, ClassNotFoundException { TypePool typePool = TypePool.Default.ofClassPath(); Class newClazz = new ByteBuddy() @@ -39,6 +39,9 @@ public class SimulateMain { // System.out.println(t22.testA("1")); TestClass t = new TestClass("abc"); System.out.println(t.testA("1")); + + t = new TestClass("abc"); + System.out.println(t.testA("1")); // TestClass t2 = null; // try {