From 47fde7ebb843f153ed1c45c41f332f6d5c6f5b1d Mon Sep 17 00:00:00 2001 From: wusheng Date: Fri, 11 Mar 2016 16:28:11 +0800 Subject: [PATCH] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E9=83=A8=E5=88=86=E4=BB=A3?= =?UTF-8?q?=E7=A0=81=EF=BC=8C=E6=8F=90=E4=BE=9B=E6=96=B0=E7=9A=84=E5=BA=94?= =?UTF-8?q?=E7=94=A8=E7=A8=8B=E5=BA=8F=E5=85=A5=E5=8F=A3=EF=BC=8C=E7=94=A8?= =?UTF-8?q?=E4=BA=8E=E5=A2=9E=E5=BC=BA=E7=B1=BB=E5=AE=9E=E7=8E=B0=E3=80=82?= =?UTF-8?q?#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