Support dynamic field and interface.

This commit is contained in:
wusheng 2017-06-30 22:00:58 +08:00
parent dd268b2eb2
commit d89a5be742
12 changed files with 19 additions and 111 deletions

View File

@ -139,6 +139,7 @@ public class SnifferConfigInitializer {
URL resource = SnifferConfigInitializer.class.getClassLoader().getSystemClassLoader().getResource(classResourcePath);
if (resource != null) {
String urlString = resource.toString();
logger.debug(urlString);
urlString = urlString.substring(urlString.indexOf("file:"), urlString.indexOf('!'));
File agentJarFile = null;
try {

View File

@ -5,6 +5,7 @@ import org.skywalking.apm.agent.core.boot.BootService;
import org.skywalking.apm.agent.core.context.TracingContext;
import org.skywalking.apm.agent.core.context.TracingContextListener;
import org.skywalking.apm.agent.core.context.trace.TraceSegment;
import org.skywalking.apm.agent.core.datacarrier.buffer.BufferStrategy;
import org.skywalking.apm.agent.core.datacarrier.consumer.IConsumer;
import static org.skywalking.apm.agent.core.conf.Config.Buffer.BUFFER_SIZE;
@ -19,6 +20,7 @@ public class DataBufferService implements BootService, IConsumer<TraceSegment>,
@Override
public void bootUp() throws Throwable {
carrier = new DataCarrier<TraceSegment>(CHANNEL_SIZE, BUFFER_SIZE);
carrier.setBufferStrategy(BufferStrategy.IF_POSSIBLE);
carrier.consume(this, 1);
TracingContext.ListenerManager.add(this);
}

View File

@ -1,8 +1,6 @@
package org.skywalking.apm.agent.core.datacarrier.buffer;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import org.skywalking.apm.agent.core.datacarrier.common.AtomicRangeInteger;
/**

View File

@ -4,16 +4,7 @@ package org.skywalking.apm.agent.core.datacarrier.buffer;
* Created by wusheng on 2016/10/25.
*/
public enum BufferStrategy {
/**
* 阻塞模式
*/
BLOCKING,
/**
* 复写模式
*/
OVERRIDE,
/**
* 尝试写入模式无法写入则返回写入失败
*/
IF_POSSIBLE
}

View File

@ -13,7 +13,7 @@ public class ConsumerThread<T> extends Thread {
private List<DataSource> dataSources;
ConsumerThread(String threadName, IConsumer<T> consumer) {
super((threadName));
super(threadName);
this.consumer = consumer;
running = false;
dataSources = new LinkedList<DataSource>();

View File

@ -23,6 +23,9 @@ public enum PluginCfg {
String pluginDefine = null;
while ((pluginDefine = reader.readLine()) != null) {
try {
if (pluginDefine == null || pluginDefine.trim().length() == 0) {
continue;
}
PluginDefine plugin = PluginDefine.build(pluginDefine);
if (plugin.enable()) {
pluginClassList.add(plugin);

View File

@ -2,24 +2,24 @@ package org.skywalking.apm.agent.core.plugin.interceptor.enhance;
import net.bytebuddy.description.method.MethodDescription;
import net.bytebuddy.dynamic.DynamicType;
import net.bytebuddy.implementation.FieldAccessor;
import net.bytebuddy.implementation.MethodDelegation;
import net.bytebuddy.implementation.SuperMethodCall;
import net.bytebuddy.implementation.bind.annotation.FieldProxy;
import net.bytebuddy.implementation.bind.annotation.Morph;
import net.bytebuddy.matcher.ElementMatchers;
import org.skywalking.apm.agent.core.plugin.AbstractClassEnhancePluginDefine;
import org.skywalking.apm.agent.core.plugin.PluginException;
import org.skywalking.apm.agent.core.plugin.interceptor.ConstructorInterceptPoint;
import org.skywalking.apm.agent.core.plugin.interceptor.EnhanceException;
import org.skywalking.apm.agent.core.plugin.interceptor.InstanceMethodsInterceptPoint;
import org.skywalking.apm.agent.core.plugin.interceptor.StaticMethodsInterceptPoint;
import org.skywalking.apm.util.StringUtil;
import org.skywalking.apm.agent.core.plugin.AbstractClassEnhancePluginDefine;
import org.skywalking.apm.logging.ILog;
import org.skywalking.apm.logging.LogManager;
import org.skywalking.apm.util.StringUtil;
import static net.bytebuddy.jar.asm.Opcodes.ACC_PRIVATE;
import static net.bytebuddy.matcher.ElementMatchers.isStatic;
import static net.bytebuddy.matcher.ElementMatchers.named;
import static net.bytebuddy.matcher.ElementMatchers.not;
/**
@ -95,8 +95,7 @@ public abstract class ClassEnhancePluginDefine extends AbstractClassEnhancePlugi
*/
newClassBuilder = newClassBuilder.defineField(CONTEXT_ATTR_NAME, Object.class, ACC_PRIVATE)
.implement(EnhancedInstance.class)
.method(named("_getSkyWalkingDynamicFiled"))
.intercept(MethodDelegation.to(EnhancedInstanceFieldGetter.class));
.intercept(FieldAccessor.ofField(CONTEXT_ATTR_NAME));
/**
* 2. enhance constructors

View File

@ -1,8 +0,0 @@
package org.skywalking.apm.agent.core.plugin.interceptor.enhance;
/**
* @author wusheng
*/
public interface Constructible {
void call(Object[] args);
}

View File

@ -1,61 +0,0 @@
package org.skywalking.apm.agent.core.plugin.interceptor.enhance;
import net.bytebuddy.implementation.bind.annotation.AllArguments;
import net.bytebuddy.implementation.bind.annotation.FieldProxy;
import net.bytebuddy.implementation.bind.annotation.Morph;
import net.bytebuddy.implementation.bind.annotation.RuntimeType;
import net.bytebuddy.implementation.bind.annotation.This;
import org.skywalking.apm.agent.core.plugin.interceptor.loader.InterceptorInstanceLoader;
import org.skywalking.apm.logging.ILog;
import org.skywalking.apm.logging.LogManager;
/**
* The actual byte-buddy's interceptor to intercept constructor methods.
* In this class, it provide a bridge between byte-buddy and sky-walking plugin.
*
* @author wusheng
*/
public class ConstructorInterWithOverrideArgs {
private static final ILog logger = LogManager.getLogger(ConstructorInterWithOverrideArgs.class);
/**
* A class full name, and instanceof {@link InstanceConstructorInterceptor}
* This name should only stay in {@link String}, the real {@link Class} type will trigger classloader failure.
* If you want to know more, please check on books about Classloader or Classloader appointment mechanism.
*/
private String constructorInterceptorClassName;
/**
* Set the name of {@link ConstructorInterWithOverrideArgs#constructorInterceptorClassName}
*
* @param constructorInterceptorClassName class full name.
*/
public ConstructorInterWithOverrideArgs(String constructorInterceptorClassName) {
this.constructorInterceptorClassName = constructorInterceptorClassName;
}
/**
* Intercept the target constructor.
*
* @param obj target class instance.
* @param dynamicFieldGetter a proxy to set the dynamic field
* @param dynamicFieldSetter a proxy to get the dynamic field
* @param allArguments all constructor arguments
*/
@RuntimeType
public void intercept(@This Object obj,
@FieldProxy(ClassEnhancePluginDefine.CONTEXT_ATTR_NAME) FieldSetter dynamicFieldSetter,
@FieldProxy(ClassEnhancePluginDefine.CONTEXT_ATTR_NAME) FieldGetter dynamicFieldGetter,
@AllArguments Object[] allArguments,
@Morph(defaultMethod = true) Constructible zuper) {
try {
InstanceConstructorInterceptor interceptor = InterceptorInstanceLoader.load(constructorInterceptorClassName, obj.getClass().getClassLoader());
interceptor.onConstruct(obj, allArguments, dynamicFieldSetter, dynamicFieldGetter);
zuper.call(allArguments);
} catch (Throwable t) {
logger.error("ConstructorInter failure.", t);
}
}
}

View File

@ -1,17 +0,0 @@
package org.skywalking.apm.agent.core.plugin.interceptor.enhance;
import net.bytebuddy.implementation.bind.annotation.FieldValue;
import net.bytebuddy.implementation.bind.annotation.RuntimeType;
/**
* Get the value of dynamic added {@link ClassEnhancePluginDefine#CONTEXT_ATTR_NAME} field
*
* @author wusheng
*/
public class EnhancedInstanceFieldGetter {
@RuntimeType
public Object intercept(
@FieldValue(ClassEnhancePluginDefine.CONTEXT_ATTR_NAME) Object fieldValue) {
return fieldValue;
}
}

View File

@ -27,7 +27,9 @@ public class GRPCChannelManager implements BootService, Runnable {
synchronized (this) {
if (channelManagerThread == null || !channelManagerThread.isAlive()) {
if (managedChannel == null || managedChannel.isTerminated() || managedChannel.isShutdown()) {
managedChannel.shutdownNow();
if (managedChannel != null) {
managedChannel.shutdownNow();
}
Thread channelManagerThread = new Thread(this, "ChannelManagerThread");
channelManagerThread.setDaemon(true);
channelManagerThread.start();

View File

@ -1,5 +1,6 @@
package org.skywalking.apm.agent;
import java.lang.instrument.Instrumentation;
import java.util.List;
import net.bytebuddy.agent.builder.AgentBuilder;
import net.bytebuddy.description.NamedElement;
@ -7,7 +8,6 @@ import net.bytebuddy.description.type.TypeDescription;
import net.bytebuddy.dynamic.DynamicType;
import net.bytebuddy.matcher.ElementMatcher;
import net.bytebuddy.utility.JavaModule;
import org.skywalking.apm.agent.junction.SkyWalkingEnhanceMatcher;
import org.skywalking.apm.agent.core.boot.ServiceManager;
import org.skywalking.apm.agent.core.conf.SnifferConfigInitializer;
import org.skywalking.apm.agent.core.logging.EasyLogResolver;
@ -15,11 +15,10 @@ import org.skywalking.apm.agent.core.plugin.AbstractClassEnhancePluginDefine;
import org.skywalking.apm.agent.core.plugin.PluginBootstrap;
import org.skywalking.apm.agent.core.plugin.PluginException;
import org.skywalking.apm.agent.core.plugin.PluginFinder;
import org.skywalking.apm.agent.junction.SkyWalkingEnhanceMatcher;
import org.skywalking.apm.logging.ILog;
import org.skywalking.apm.logging.LogManager;
import java.lang.instrument.Instrumentation;
import static net.bytebuddy.matcher.ElementMatchers.isInterface;
import static net.bytebuddy.matcher.ElementMatchers.not;
@ -76,7 +75,9 @@ public class SkyWalkingAgent {
@Override
public void onTransformation(TypeDescription typeDescription, ClassLoader classLoader, JavaModule module,
boolean loaded, DynamicType dynamicType) {
if (logger.isDebugEnable()) {
logger.debug("On Transformation class {}.", typeDescription.getName());
}
}
@Override
@ -92,9 +93,6 @@ public class SkyWalkingAgent {
@Override
public void onComplete(String typeName, ClassLoader classLoader, JavaModule module, boolean loaded) {
if(logger.isDebugEnable()){
logger.debug("Enhance class {} completed.", typeName);
}
}
}).installOn(instrumentation);
}