提交 252e50cd 编写于 作者: Z zhang.xin

Merge remote-tracking branch 'origin/master'

package com.ai.cloud.skywalking.conf; 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.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.lang.reflect.Field; import java.lang.reflect.Field;
import java.lang.reflect.Modifier; import java.lang.reflect.Modifier;
import java.util.LinkedList; import java.util.LinkedList;
import java.util.Properties; 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 { public class ConfigInitializer {
private static Logger logger = Logger.getLogger(ConfigInitializer.class.getName()); private static Logger logger = LogManager.getLogger(ConfigInitializer.class);
public static void initialize() { public static void initialize() {
InputStream inputStream = ConfigInitializer.class.getResourceAsStream("/sky-walking.auth"); InputStream inputStream = ConfigInitializer.class.getResourceAsStream("/sky-walking.auth");
if (inputStream == null) { 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 { } else {
try { try {
Properties properties = new Properties(); Properties properties = new Properties();
properties.load(inputStream); properties.load(inputStream);
initNextLevel(properties, Config.class, new ConfigDesc()); initNextLevel(properties, Config.class, new ConfigDesc());
AuthDesc.isAuth = Boolean.valueOf(System.getenv(AUTH_SYSTEM_ENV_NAME)); 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){ if(!AuthDesc.isAuth && AUTH_OVERRIDE){
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) { } 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) { } 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);
} }
} }
} }
......
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<URL> 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();
}
}
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<String> interceptorClassList = new HashSet<String>();
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<String> getInterceptorClassList(){
return interceptorClassList;
}
}
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<URL> getResources(){
Enumeration<URL> 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;
}
}
package com.ai.cloud.skywalking.plugin;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
/**
* 替代应用函数的main函数入口,确保在程序入口处运行 <br/>
* 用于替代-javaagent的另一种模式 <br/>
*
* @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);
}
}
}
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<String> 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 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 <br/>
* 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();
/**
* define class as origin class name. and inject to classloader. <br/>
* new class need:<br/>
* 1.implement com.ai.cloud.skywalking.plugin.interceptor.IEnhancedClassInstanceContext(); <br/>
* 2.add field '_$EnhancedClassInstanceContext' of type EnhancedClassInstanceContext
* 3.intercept constructor and method if required by interceptorDefineClass
*/
}
}
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<Object, Object> context = new HashMap<Object, Object>();
}
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);
}
package com.ai.cloud.skywalking.plugin.interceptor;
/**
* 被增强的类,会实现此接口,用于快速获取实例级属性上下文扩展<br/>
* @see com.ai.cloud.skywalking.plugin.interceptor.EnhanceClazz4Interceptor.enhance0()
*
* @author wusheng
*
*/
public interface IEnhancedClassInstanceContext {
public EnhancedClassInstanceContext getEnhancedClassInstanceContext();
}
package com.ai.cloud.skywalking.plugin.interceptor;
public interface InterceptorDefine {
public String getBeInterceptedClassName();
public String[] getBeInterceptedMethods();
public IAroundInterceptor instance();
}
...@@ -12,7 +12,7 @@ import com.ai.cloud.skywalking.conf.Config; ...@@ -12,7 +12,7 @@ import com.ai.cloud.skywalking.conf.Config;
import com.ai.cloud.skywalking.util.BuriedPointMachineUtil; import com.ai.cloud.skywalking.util.BuriedPointMachineUtil;
public class SDKHealthCollector extends Thread { public class SDKHealthCollector extends Thread {
private Logger logger = LogManager.getLogger(SDKHealthCollector.class); private static Logger logger = LogManager.getLogger(SDKHealthCollector.class);
private static Map<String, HeathReading> heathReadings = new ConcurrentHashMap<String, HeathReading>(); private static Map<String, HeathReading> heathReadings = new ConcurrentHashMap<String, HeathReading>();
......
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]);
}
}
}
...@@ -7,12 +7,13 @@ import net.bytebuddy.implementation.bind.annotation.AllArguments; ...@@ -7,12 +7,13 @@ import net.bytebuddy.implementation.bind.annotation.AllArguments;
import net.bytebuddy.implementation.bind.annotation.Origin; import net.bytebuddy.implementation.bind.annotation.Origin;
import net.bytebuddy.implementation.bind.annotation.RuntimeType; import net.bytebuddy.implementation.bind.annotation.RuntimeType;
import net.bytebuddy.implementation.bind.annotation.SuperCall; import net.bytebuddy.implementation.bind.annotation.SuperCall;
import net.bytebuddy.implementation.bind.annotation.This;
public class Interceptor{ public class MethodInterceptor{
@RuntimeType @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 { try {
return "intercept_" + zuper.call(); return method.getName() + ":intercept_" + zuper.call();
} catch (Exception e) { } catch (Exception e) {
// TODO Auto-generated catch block // TODO Auto-generated catch block
e.printStackTrace(); e.printStackTrace();
......
package test.ai.cloud.bytebuddy; 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.ByteBuddy;
import net.bytebuddy.dynamic.ClassFileLocator; import net.bytebuddy.dynamic.ClassFileLocator;
import net.bytebuddy.dynamic.loading.ClassLoadingStrategy; import net.bytebuddy.dynamic.loading.ClassLoadingStrategy;
import net.bytebuddy.implementation.MethodDelegation; import net.bytebuddy.implementation.MethodDelegation;
import net.bytebuddy.implementation.SuperMethodCall;
import net.bytebuddy.pool.TypePool; import net.bytebuddy.pool.TypePool;
public class SimulateMain { public class SimulateMain {
public static void main(String[] args) throws NoSuchFieldException, public static void main(String[] args) throws NoSuchFieldException,
SecurityException, InstantiationException, IllegalAccessException { SecurityException, InstantiationException, IllegalAccessException, ClassNotFoundException {
TypePool typePool = TypePool.Default.ofClassPath(); 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() Class<?> newClazz = new ByteBuddy()
.subclass(newClazzObj.getClass()) .redefine(
.method(named("testA")) typePool.describe("test.ai.cloud.bytebuddy.TestClass")
.intercept(MethodDelegation.to(new Interceptor())) .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") .name("test.ai.cloud.bytebuddy.TestClass")
.make() .make()
.load(ClassLoader.getSystemClassLoader(), .load(ClassLoader.getSystemClassLoader(),
ClassLoadingStrategy.Default.INJECTION).getLoaded().newInstance()); ClassLoadingStrategy.Default.INJECTION).getLoaded()
.newInstance());
//System.out.println(t22.testA("1")); // System.out.println(t22.testA("1"));
TestClass t = new TestClass("abc");
TestClass t = new TestClass();
System.out.println(t.testA("1")); System.out.println(t.testA("1"));
TestClass t2 = null; t = new TestClass("abc");
try { System.out.println(t.testA("1"));
t2 = (TestClass)Class.forName("test.ai.cloud.bytebuddy.TestClass").newInstance();
} catch (ClassNotFoundException e) { // TestClass t2 = null;
// TODO Auto-generated catch block // try {
e.printStackTrace(); // t2 = (TestClass) Class.forName("test.ai.cloud.bytebuddy.TestClass")
} // .newInstance();
System.out.println(t2.testA("1")); // } catch (ClassNotFoundException e) {
// // TODO Auto-generated catch block
// e.printStackTrace();
// }
// System.out.println(t2.testA("1"));
} }
} }
package test.ai.cloud.bytebuddy; package test.ai.cloud.bytebuddy;
public class TestClass { 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){ public String testA(String aa){
// throw new RuntimeException("adfasdfas"); // throw new RuntimeException("adfasdfas");
return "TestClass.testA"; return "TestClass.testA";
......
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();
}
}
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="debug">
<Appenders>
<Console name="Console" target="SYSTEM_OUT">
<PatternLayout pattern="%d [%t](%F:%L) %-5level %logger{36} - %msg%n"/>
</Console>
</Appenders>
<Loggers>
<Root level="debug">
<AppenderRef ref="Console"/>
</Root>
</Loggers>
</Configuration>
\ No newline at end of file
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册