使用新的插件机制。扩展插件能力。
This commit is contained in:
parent
4206839c36
commit
722f4ba98f
|
|
@ -0,0 +1,6 @@
|
|||
package com.ai.cloud.skywalking.plugin;
|
||||
|
||||
|
||||
public interface IPlugin {
|
||||
public void define() throws PluginException;
|
||||
}
|
||||
|
|
@ -3,19 +3,24 @@ package com.ai.cloud.skywalking.plugin;
|
|||
import java.net.URL;
|
||||
import java.util.List;
|
||||
|
||||
import net.bytebuddy.pool.TypePool;
|
||||
|
||||
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 static TypePool CLASS_TYPE_POOL = null;
|
||||
|
||||
public void start() {
|
||||
if (!AuthDesc.isAuth()) {
|
||||
return;
|
||||
}
|
||||
|
||||
CLASS_TYPE_POOL = TypePool.Default.ofClassPath();
|
||||
|
||||
PluginResourcesResolver resolver = new PluginResourcesResolver();
|
||||
List<URL> resources = resolver.getResources();
|
||||
|
|
@ -32,9 +37,22 @@ public class PluginBootstrap {
|
|||
logger.error("plugin [{}] init failure.", pluginUrl, t);
|
||||
}
|
||||
}
|
||||
|
||||
List<String> pluginClassList = PluginCfg.CFG
|
||||
.getPluginClassList();
|
||||
|
||||
EnhanceClazz4Interceptor enhanceClazz4Interceptor = new EnhanceClazz4Interceptor();
|
||||
enhanceClazz4Interceptor.enhance();
|
||||
for (String pluginClassName : pluginClassList) {
|
||||
try {
|
||||
logger.debug("prepare to enhance class by plugin {}.",
|
||||
pluginClassName);
|
||||
IPlugin plugin = (IPlugin) Class.forName(
|
||||
pluginClassName).newInstance();
|
||||
plugin.define();
|
||||
} catch (Throwable t) {
|
||||
logger.error("prepare to enhance class by plugin [{}] failure.",
|
||||
pluginClassName, t);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -12,17 +12,17 @@ import com.ai.cloud.skywalking.util.StringUtil;
|
|||
public class PluginCfg {
|
||||
public final static PluginCfg CFG = new PluginCfg();
|
||||
|
||||
private List<String> interceptorClassList = new ArrayList<String>();
|
||||
private List<String> pluginClassList = new ArrayList<String>();
|
||||
|
||||
private PluginCfg(){}
|
||||
|
||||
void load(InputStream input) throws IOException{
|
||||
try{
|
||||
BufferedReader reader = new BufferedReader(new InputStreamReader(input));
|
||||
String interceptorDefineClassName = null;
|
||||
while((interceptorDefineClassName = reader.readLine()) != null){
|
||||
if(!StringUtil.isEmpty(interceptorDefineClassName)){
|
||||
interceptorClassList.add(interceptorDefineClassName.trim());
|
||||
String pluginDefineClassName = null;
|
||||
while((pluginDefineClassName = reader.readLine()) != null){
|
||||
if(!StringUtil.isEmpty(pluginDefineClassName)){
|
||||
pluginClassList.add(pluginDefineClassName.trim());
|
||||
}
|
||||
}
|
||||
}finally{
|
||||
|
|
@ -30,7 +30,7 @@ public class PluginCfg {
|
|||
}
|
||||
}
|
||||
|
||||
public List<String> getInterceptorClassList(){
|
||||
return interceptorClassList;
|
||||
public List<String> getPluginClassList(){
|
||||
return pluginClassList;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,13 @@
|
|||
package com.ai.cloud.skywalking.plugin;
|
||||
|
||||
public class PluginException extends Exception {
|
||||
private static final long serialVersionUID = -6020188711867490724L;
|
||||
|
||||
public PluginException(String message) {
|
||||
super(message);
|
||||
}
|
||||
|
||||
public PluginException(String message, Throwable cause) {
|
||||
super(message, cause);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,16 @@
|
|||
package com.ai.cloud.skywalking.plugin.boot;
|
||||
|
||||
import com.ai.cloud.skywalking.plugin.PluginException;
|
||||
|
||||
public class BootException extends PluginException {
|
||||
private static final long serialVersionUID = 8618884011525098003L;
|
||||
|
||||
public BootException(String message) {
|
||||
super(message);
|
||||
}
|
||||
|
||||
public BootException(String message, Throwable cause) {
|
||||
super(message, cause);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,15 @@
|
|||
package com.ai.cloud.skywalking.plugin.boot;
|
||||
|
||||
import com.ai.cloud.skywalking.plugin.IPlugin;
|
||||
import com.ai.cloud.skywalking.plugin.PluginException;
|
||||
|
||||
public abstract class BootPluginDefine implements IPlugin {
|
||||
|
||||
@Override
|
||||
public void define() throws PluginException {
|
||||
this.boot();
|
||||
}
|
||||
|
||||
protected abstract void boot() throws BootException;
|
||||
|
||||
}
|
||||
|
|
@ -21,7 +21,7 @@ public class ClassConstructorInterceptor {
|
|||
@RuntimeType
|
||||
public void intercept(
|
||||
@This Object obj,
|
||||
@FieldProxy(EnhanceClazz4Interceptor.contextAttrName) FieldSetter accessor,
|
||||
@FieldProxy(InterceptorPluginDefine.contextAttrName) FieldSetter accessor,
|
||||
@AllArguments Object[] allArguments) {
|
||||
try {
|
||||
EnhancedClassInstanceContext context = new EnhancedClassInstanceContext();
|
||||
|
|
|
|||
|
|
@ -35,7 +35,7 @@ public class ClassMethodInterceptor {
|
|||
@AllArguments Object[] allArguments,
|
||||
@Origin Method method,
|
||||
@SuperCall Callable<?> zuper,
|
||||
@FieldValue(EnhanceClazz4Interceptor.contextAttrName) EnhancedClassInstanceContext instanceContext)
|
||||
@FieldValue(InterceptorPluginDefine.contextAttrName) EnhancedClassInstanceContext instanceContext)
|
||||
throws Exception {
|
||||
MethodInvokeContext interceptorContext = new MethodInvokeContext(obj,
|
||||
method.getName(), allArguments);
|
||||
|
|
|
|||
|
|
@ -1,6 +1,8 @@
|
|||
package com.ai.cloud.skywalking.plugin.interceptor;
|
||||
|
||||
public class EnhanceException extends Exception {
|
||||
import com.ai.cloud.skywalking.plugin.PluginException;
|
||||
|
||||
public class EnhanceException extends PluginException {
|
||||
private static final long serialVersionUID = -2234782755784217255L;
|
||||
|
||||
public EnhanceException(String message) {
|
||||
|
|
|
|||
|
|
@ -1,25 +0,0 @@
|
|||
package com.ai.cloud.skywalking.plugin.interceptor;
|
||||
|
||||
public interface InterceptorDefine {
|
||||
/**
|
||||
* 返回要被增强的类,应当返回类全名
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public String getBeInterceptedClassName();
|
||||
|
||||
/**
|
||||
* 返回需要被增强的方法列表
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public MethodMatcher[] getBeInterceptedMethodsMatchers();
|
||||
|
||||
/**
|
||||
* 返回增强拦截器的实现<br/>
|
||||
* 每个拦截器在同一个被增强类的内部,保持单例
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public IAroundInterceptor instance();
|
||||
}
|
||||
|
|
@ -2,9 +2,7 @@ package com.ai.cloud.skywalking.plugin.interceptor;
|
|||
|
||||
import static net.bytebuddy.matcher.ElementMatchers.any;
|
||||
import static net.bytebuddy.matcher.ElementMatchers.not;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import static com.ai.cloud.skywalking.plugin.PluginBootstrap.CLASS_TYPE_POOL;
|
||||
import net.bytebuddy.ByteBuddy;
|
||||
import net.bytebuddy.description.method.MethodDescription;
|
||||
import net.bytebuddy.dynamic.ClassFileLocator;
|
||||
|
|
@ -21,44 +19,21 @@ import net.bytebuddy.pool.TypePool.Resolution;
|
|||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
|
||||
import com.ai.cloud.skywalking.plugin.PluginCfg;
|
||||
import com.ai.cloud.skywalking.plugin.IPlugin;
|
||||
import com.ai.cloud.skywalking.plugin.PluginException;
|
||||
import com.ai.cloud.skywalking.util.StringUtil;
|
||||
|
||||
public class EnhanceClazz4Interceptor {
|
||||
private static Logger logger = LogManager
|
||||
.getLogger(EnhanceClazz4Interceptor.class);
|
||||
|
||||
private TypePool typePool;
|
||||
|
||||
public abstract class InterceptorPluginDefine implements IPlugin {
|
||||
private static Logger logger = LogManager.getLogger(InterceptorPluginDefine.class);
|
||||
|
||||
public static final String contextAttrName = "_$EnhancedClassInstanceContext";
|
||||
|
||||
|
||||
public EnhanceClazz4Interceptor() {
|
||||
typePool = TypePool.Default.ofClassPath();
|
||||
}
|
||||
|
||||
public void enhance() {
|
||||
List<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, EnhanceException {
|
||||
logger.debug("prepare to enhance class by {}.",
|
||||
interceptorDefineClassName);
|
||||
InterceptorDefine define = (InterceptorDefine) Class.forName(
|
||||
interceptorDefineClassName).newInstance();
|
||||
|
||||
String enhanceOriginClassName = define.getBeInterceptedClassName();
|
||||
@Override
|
||||
public void define() throws PluginException {
|
||||
String interceptorDefineClassName = this.getClass().getName();
|
||||
|
||||
String enhanceOriginClassName = getBeInterceptedClassName();
|
||||
if (StringUtil.isEmpty(enhanceOriginClassName)) {
|
||||
logger.warn("classname of being intercepted is not defined by {}.",
|
||||
interceptorDefineClassName);
|
||||
|
|
@ -68,7 +43,7 @@ public class EnhanceClazz4Interceptor {
|
|||
logger.debug("prepare to enhance class {} by {}.",
|
||||
enhanceOriginClassName, interceptorDefineClassName);
|
||||
|
||||
Resolution resolution = typePool.describe(enhanceOriginClassName);
|
||||
Resolution resolution = CLASS_TYPE_POOL.describe(enhanceOriginClassName);
|
||||
if (!resolution.isResolved()) {
|
||||
logger.warn("class {} can't be resolved, enhance by {} failue.",
|
||||
enhanceOriginClassName, interceptorDefineClassName);
|
||||
|
|
@ -92,7 +67,7 @@ public class EnhanceClazz4Interceptor {
|
|||
* 2.intercept constructor by default, and intercept method which it's
|
||||
* required by interceptorDefineClass. <br/>
|
||||
*/
|
||||
IAroundInterceptor interceptor = define.instance();
|
||||
IAroundInterceptor interceptor = instance();
|
||||
if (interceptor == null) {
|
||||
throw new EnhanceException("no IAroundInterceptor instance. ");
|
||||
}
|
||||
|
|
@ -109,7 +84,7 @@ public class EnhanceClazz4Interceptor {
|
|||
FieldGetter.class,
|
||||
FieldSetter.class))));
|
||||
|
||||
MethodMatcher[] methodMatchers = define.getBeInterceptedMethodsMatchers();
|
||||
MethodMatcher[] methodMatchers = getBeInterceptedMethodsMatchers();
|
||||
ClassMethodInterceptor classMethodInterceptor = new ClassMethodInterceptor(
|
||||
interceptor);
|
||||
|
||||
|
|
@ -151,5 +126,27 @@ public class EnhanceClazz4Interceptor {
|
|||
|
||||
logger.debug("enhance class {} by {} completely.",
|
||||
enhanceOriginClassName, interceptorDefineClassName);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 返回要被增强的类,应当返回类全名
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public abstract String getBeInterceptedClassName();
|
||||
|
||||
/**
|
||||
* 返回需要被增强的方法列表
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public abstract MethodMatcher[] getBeInterceptedMethodsMatchers();
|
||||
|
||||
/**
|
||||
* 返回增强拦截器的实现<br/>
|
||||
* 每个拦截器在同一个被增强类的内部,保持单例
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public abstract IAroundInterceptor instance();
|
||||
}
|
||||
|
|
@ -2,10 +2,12 @@ package test.ai.cloud.matcher;
|
|||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import com.ai.cloud.skywalking.plugin.PluginBootstrap;
|
||||
|
||||
public class ExclusionMatcherTest extends TestCase{
|
||||
|
||||
@Test
|
||||
public void testMatcher() throws ClassNotFoundException, IllegalAccessException, InstantiationException, InterruptedException {
|
||||
new PluginBootstrap().start();
|
||||
TestMatcherClass testMatcherClass = (TestMatcherClass) Class.forName("test.ai.cloud.matcher.TestMatcherClass").newInstance();
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
package test.ai.cloud.matcher;
|
||||
|
||||
import com.ai.cloud.skywalking.plugin.interceptor.IAroundInterceptor;
|
||||
import com.ai.cloud.skywalking.plugin.interceptor.InterceptorDefine;
|
||||
import com.ai.cloud.skywalking.plugin.interceptor.InterceptorPluginDefine;
|
||||
import com.ai.cloud.skywalking.plugin.interceptor.MethodMatcher;
|
||||
import com.ai.cloud.skywalking.plugin.interceptor.matcher.MethodsExclusiveMatcher;
|
||||
import com.ai.cloud.skywalking.plugin.interceptor.matcher.PrivateMethodMatcher;
|
||||
|
|
@ -10,7 +10,7 @@ import com.ai.cloud.skywalking.plugin.interceptor.matcher.SimpleMethodMatcher;
|
|||
/**
|
||||
* Created by xin on 16-6-8.
|
||||
*/
|
||||
public class TestMatcherDefine implements InterceptorDefine {
|
||||
public class TestMatcherDefine extends InterceptorPluginDefine {
|
||||
@Override
|
||||
public String getBeInterceptedClassName() {
|
||||
return "test.ai.cloud.matcher.TestMatcherClass";
|
||||
|
|
|
|||
|
|
@ -1,11 +1,11 @@
|
|||
package test.ai.cloud.plugin;
|
||||
|
||||
import com.ai.cloud.skywalking.plugin.interceptor.IAroundInterceptor;
|
||||
import com.ai.cloud.skywalking.plugin.interceptor.InterceptorDefine;
|
||||
import com.ai.cloud.skywalking.plugin.interceptor.InterceptorPluginDefine;
|
||||
import com.ai.cloud.skywalking.plugin.interceptor.MethodMatcher;
|
||||
import com.ai.cloud.skywalking.plugin.interceptor.matcher.SimpleMethodMatcher;
|
||||
|
||||
public class TestInterceptorDefine implements InterceptorDefine {
|
||||
public class TestInterceptorDefine extends InterceptorPluginDefine {
|
||||
|
||||
@Override
|
||||
public String getBeInterceptedClassName() {
|
||||
|
|
|
|||
|
|
@ -3,13 +3,13 @@ package org.skywalking.httpClient.v4.plugin.dubbox.rest.attachment;
|
|||
import org.skywalking.httpClient.v4.plugin.HttpClientExecuteInterceptor;
|
||||
|
||||
import com.ai.cloud.skywalking.plugin.interceptor.IAroundInterceptor;
|
||||
import com.ai.cloud.skywalking.plugin.interceptor.InterceptorDefine;
|
||||
import com.ai.cloud.skywalking.plugin.interceptor.InterceptorPluginDefine;
|
||||
import com.ai.cloud.skywalking.plugin.interceptor.MethodMatcher;
|
||||
|
||||
public class DubboxRestHeadSetterAttachment implements InterceptorDefine {
|
||||
public class DubboxRestHeadSetterAttachment extends InterceptorPluginDefine {
|
||||
|
||||
/**
|
||||
* this method is called as InterceptorDefine<br/>
|
||||
* this method is called as InterceptorPluginDefine<br/>
|
||||
* don't return be intercepted classname, <br/>
|
||||
* just run as a pre setter of attribute:HttpClientExecuteInterceptor.TRACE_HEAD_NAME
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -3,9 +3,9 @@ package org.skywalking.httpClient.v4.plugin.define;
|
|||
import org.skywalking.httpClient.v4.plugin.HttpClientExecuteInterceptor;
|
||||
|
||||
import com.ai.cloud.skywalking.plugin.interceptor.IAroundInterceptor;
|
||||
import com.ai.cloud.skywalking.plugin.interceptor.InterceptorDefine;
|
||||
import com.ai.cloud.skywalking.plugin.interceptor.InterceptorPluginDefine;
|
||||
|
||||
public abstract class HttpClientPluginDefine implements InterceptorDefine {
|
||||
public abstract class HttpClientPluginDefine extends InterceptorPluginDefine {
|
||||
|
||||
@Override
|
||||
public IAroundInterceptor instance() {
|
||||
|
|
|
|||
|
|
@ -2,11 +2,11 @@ package com.ai.cloud.skywalking.jedis.v2.plugin.define;
|
|||
|
||||
import com.ai.cloud.skywalking.jedis.v2.plugin.JedisClusterInterceptor;
|
||||
import com.ai.cloud.skywalking.plugin.interceptor.IAroundInterceptor;
|
||||
import com.ai.cloud.skywalking.plugin.interceptor.InterceptorDefine;
|
||||
import com.ai.cloud.skywalking.plugin.interceptor.InterceptorPluginDefine;
|
||||
import com.ai.cloud.skywalking.plugin.interceptor.MethodMatcher;
|
||||
import com.ai.cloud.skywalking.plugin.interceptor.matcher.AnyMethodsMatcher;
|
||||
|
||||
public class JedisClusterPluginDefine implements InterceptorDefine {
|
||||
public class JedisClusterPluginDefine extends InterceptorPluginDefine {
|
||||
|
||||
@Override
|
||||
public String getBeInterceptedClassName() {
|
||||
|
|
|
|||
|
|
@ -2,13 +2,13 @@ package com.ai.cloud.skywalking.jedis.v2.plugin.define;
|
|||
|
||||
import com.ai.cloud.skywalking.jedis.v2.plugin.JedisInterceptor;
|
||||
import com.ai.cloud.skywalking.plugin.interceptor.IAroundInterceptor;
|
||||
import com.ai.cloud.skywalking.plugin.interceptor.InterceptorDefine;
|
||||
import com.ai.cloud.skywalking.plugin.interceptor.InterceptorPluginDefine;
|
||||
import com.ai.cloud.skywalking.plugin.interceptor.MethodMatcher;
|
||||
import com.ai.cloud.skywalking.plugin.interceptor.matcher.MethodsExclusiveMatcher;
|
||||
import com.ai.cloud.skywalking.plugin.interceptor.matcher.PrivateMethodMatcher;
|
||||
import com.ai.cloud.skywalking.plugin.interceptor.matcher.SimpleMethodMatcher;
|
||||
|
||||
public class JedisPluginDefine implements InterceptorDefine {
|
||||
public class JedisPluginDefine extends InterceptorPluginDefine {
|
||||
|
||||
@Override
|
||||
public String getBeInterceptedClassName() {
|
||||
|
|
|
|||
|
|
@ -1,11 +1,11 @@
|
|||
package com.ai.cloud.skywalking.plugin.mysql;
|
||||
|
||||
import com.ai.cloud.skywalking.plugin.interceptor.IAroundInterceptor;
|
||||
import com.ai.cloud.skywalking.plugin.interceptor.InterceptorDefine;
|
||||
import com.ai.cloud.skywalking.plugin.interceptor.InterceptorPluginDefine;
|
||||
import com.ai.cloud.skywalking.plugin.interceptor.MethodMatcher;
|
||||
import com.ai.cloud.skywalking.plugin.interceptor.matcher.SimpleMethodMatcher;
|
||||
|
||||
public class ConnectionPluginDefine implements InterceptorDefine {
|
||||
public class ConnectionPluginDefine extends InterceptorPluginDefine {
|
||||
|
||||
@Override
|
||||
public String getBeInterceptedClassName() {
|
||||
|
|
|
|||
Loading…
Reference in New Issue