提交 701b6afa 编写于 作者: wu-sheng's avatar wu-sheng

Fix operationName of entry span didn’t reset. And optimize interceptor initialization.

上级 b3fe61ae
......@@ -95,7 +95,7 @@ public class TracingContext implements AbstractTracerContext {
@Override
public AbstractSpan createEntrySpan(final String operationName) {
AbstractTracingSpan entrySpan;
AbstractTracingSpan parentSpan = peek();
final AbstractTracingSpan parentSpan = peek();
final int parentSpanId = parentSpan == null ? -1 : parentSpan.getSpanId();
if (parentSpan == null) {
entrySpan = (AbstractTracingSpan)DictionaryManager.findOperationNameCodeSection()
......@@ -112,7 +112,18 @@ public class TracingContext implements AbstractTracerContext {
entrySpan.start();
return push(entrySpan);
} else if (parentSpan.isEntry()) {
return parentSpan.start();
entrySpan = (AbstractTracingSpan)DictionaryManager.findOperationNameCodeSection()
.find(segment.getApplicationId(), operationName)
.doInCondition(new PossibleFound.FoundAndObtain() {
@Override public Object doProcess(int operationId) {
return parentSpan.setOperationId(operationId);
}
}, new PossibleFound.NotFoundAndObtain() {
@Override public Object doProcess() {
return parentSpan.setOperationName(operationName);
}
});
return entrySpan.start();
} else {
throw new IllegalStateException("The Entry Span can't be the child of Non-Entry Span");
}
......
......@@ -113,6 +113,16 @@ public abstract class AbstractTracingSpan implements AbstractSpan {
return this;
}
public AbstractTracingSpan setOperationName(String operationName) {
this.operationName = operationName;
return this;
}
public AbstractTracingSpan setOperationId(int operationId) {
this.operationId = operationId;
return this;
}
public int getSpanId() {
return spanId;
}
......
......@@ -104,7 +104,7 @@ public abstract class ClassEnhancePluginDefine extends AbstractClassEnhancePlugi
for (ConstructorInterceptPoint constructorInterceptPoint : constructorInterceptPoints) {
newClassBuilder = newClassBuilder.constructor(ElementMatchers.<MethodDescription>any()).intercept(SuperMethodCall.INSTANCE
.andThen(MethodDelegation.withDefaultConfiguration()
.to(new ConstructorInter(constructorInterceptPoint.getConstructorInterceptor()))
.to(new ConstructorInter(constructorInterceptPoint.getConstructorInterceptor(), classLoader))
)
);
}
......@@ -135,7 +135,7 @@ public abstract class ClassEnhancePluginDefine extends AbstractClassEnhancePlugi
newClassBuilder.method(not(isStatic()).and(instanceMethodsInterceptPoint.getMethodsMatcher()))
.intercept(
MethodDelegation.withDefaultConfiguration()
.to(new InstMethodsInter(interceptor))
.to(new InstMethodsInter(interceptor, classLoader))
);
}
}
......
package org.skywalking.apm.agent.core.plugin.interceptor.enhance;
import java.lang.reflect.InvocationTargetException;
import net.bytebuddy.implementation.bind.annotation.AllArguments;
import net.bytebuddy.implementation.bind.annotation.FieldProxy;
import net.bytebuddy.implementation.bind.annotation.RuntimeType;
import net.bytebuddy.implementation.bind.annotation.This;
import org.skywalking.apm.agent.core.plugin.PluginException;
import org.skywalking.apm.agent.core.plugin.interceptor.loader.InterceptorInstanceLoader;
import org.skywalking.apm.logging.ILog;
import org.skywalking.apm.logging.LogManager;
......@@ -18,19 +20,21 @@ public class ConstructorInter {
private static final ILog logger = LogManager.getLogger(ConstructorInter.class);
/**
* A class full name, and instanceof {@link InstanceConstructorInterceptor}
* An {@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;
private InstanceConstructorInterceptor interceptor;
/**
* Set the name of {@link ConstructorInter#constructorInterceptorClassName}
*
* @param constructorInterceptorClassName class full name.
*/
public ConstructorInter(String constructorInterceptorClassName) {
this.constructorInterceptorClassName = constructorInterceptorClassName;
public ConstructorInter(String constructorInterceptorClassName, ClassLoader classLoader) throws PluginException {
try {
interceptor = InterceptorInstanceLoader.load(constructorInterceptorClassName, classLoader);
} catch (Throwable t) {
throw new PluginException("Can't create InstanceConstructorInterceptor.", t);
}
}
/**
......@@ -43,7 +47,6 @@ public class ConstructorInter {
public void intercept(@This Object obj,
@AllArguments Object[] allArguments) {
try {
InstanceConstructorInterceptor interceptor = InterceptorInstanceLoader.load(constructorInterceptorClassName, obj.getClass().getClassLoader());
EnhancedInstance targetObject = (EnhancedInstance)obj;
interceptor.onConstruct(targetObject, allArguments);
......
package org.skywalking.apm.agent.core.plugin.interceptor.enhance;
import net.bytebuddy.implementation.bind.annotation.*;
import org.skywalking.apm.agent.core.plugin.PluginException;
import org.skywalking.apm.agent.core.plugin.interceptor.loader.InterceptorInstanceLoader;
import org.skywalking.apm.logging.ILog;
import org.skywalking.apm.logging.LogManager;
......@@ -18,19 +19,21 @@ public class InstMethodsInter {
private static final ILog logger = LogManager.getLogger(InstMethodsInter.class);
/**
* A class full name, and instanceof {@link InstanceMethodsAroundInterceptor}
* An {@link InstanceMethodsAroundInterceptor}
* 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 instanceMethodsAroundInterceptorClassName;
private InstanceMethodsAroundInterceptor interceptor;
/**
* Set the name of {@link InstMethodsInter#instanceMethodsAroundInterceptorClassName}
*
* @param instanceMethodsAroundInterceptorClassName class full name.
*/
public InstMethodsInter(String instanceMethodsAroundInterceptorClassName) {
this.instanceMethodsAroundInterceptorClassName = instanceMethodsAroundInterceptorClassName;
public InstMethodsInter(String instanceMethodsAroundInterceptorClassName, ClassLoader classLoader) {
try {
interceptor = InterceptorInstanceLoader.load(instanceMethodsAroundInterceptorClassName, classLoader);
} catch (Throwable t) {
throw new PluginException("Can't create InstanceMethodsAroundInterceptor.", t);
}
}
/**
......@@ -50,8 +53,6 @@ public class InstMethodsInter {
@SuperCall Callable<?> zuper,
@Origin Method method
) throws Throwable {
InstanceMethodsAroundInterceptor interceptor = InterceptorInstanceLoader
.load(instanceMethodsAroundInterceptorClassName, obj.getClass().getClassLoader());
EnhancedInstance targetObject = (EnhancedInstance)obj;
MethodInterceptResult result = new MethodInterceptResult();
......
......@@ -7,6 +7,7 @@ import net.bytebuddy.implementation.bind.annotation.Morph;
import net.bytebuddy.implementation.bind.annotation.Origin;
import net.bytebuddy.implementation.bind.annotation.RuntimeType;
import net.bytebuddy.implementation.bind.annotation.This;
import org.skywalking.apm.agent.core.plugin.PluginException;
import org.skywalking.apm.agent.core.plugin.interceptor.loader.InterceptorInstanceLoader;
import org.skywalking.apm.logging.ILog;
import org.skywalking.apm.logging.LogManager;
......@@ -21,19 +22,21 @@ public class InstMethodsInterWithOverrideArgs {
private static final ILog logger = LogManager.getLogger(InstMethodsInterWithOverrideArgs.class);
/**
* A class full name, and instanceof {@link InstanceMethodsAroundInterceptor}
* An {@link InstanceMethodsAroundInterceptor}
* 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 instanceMethodsAroundInterceptorClassName;
private InstanceMethodsAroundInterceptor interceptor;
/**
* Set the name of {@link InstMethodsInterWithOverrideArgs#instanceMethodsAroundInterceptorClassName}
*
* @param instanceMethodsAroundInterceptorClassName class full name.
*/
public InstMethodsInterWithOverrideArgs(String instanceMethodsAroundInterceptorClassName) {
this.instanceMethodsAroundInterceptorClassName = instanceMethodsAroundInterceptorClassName;
public InstMethodsInterWithOverrideArgs(String instanceMethodsAroundInterceptorClassName, ClassLoader classLoader) {
try {
interceptor = InterceptorInstanceLoader.load(instanceMethodsAroundInterceptorClassName, classLoader);
} catch (Throwable t) {
throw new PluginException("Can't create InstanceMethodsAroundInterceptor.", t);
}
}
/**
......@@ -53,8 +56,6 @@ public class InstMethodsInterWithOverrideArgs {
@Origin Method method,
@Morph(defaultMethod = true) OverrideCallable zuper
) throws Throwable {
InstanceMethodsAroundInterceptor interceptor = InterceptorInstanceLoader
.load(instanceMethodsAroundInterceptorClassName, obj.getClass().getClassLoader());
EnhancedInstance targetObject = (EnhancedInstance)obj;
MethodInterceptResult result = new MethodInterceptResult();
......
......@@ -38,6 +38,9 @@ public class InterceptorInstanceLoader {
public static <T> T load(String className, ClassLoader targetClassLoader)
throws InvocationTargetException, IllegalAccessException, InstantiationException, ClassNotFoundException {
if (targetClassLoader == null) {
targetClassLoader = InterceptorInstanceLoader.class.getClassLoader();
}
String instanceKey = className + "_OF_" + targetClassLoader.getClass().getName() + "@" + Integer.toHexString(targetClassLoader.hashCode());
Object inst = INSTANCE_CACHE.get(instanceKey);
if (inst == null) {
......@@ -66,14 +69,14 @@ public class InterceptorInstanceLoader {
}
}
return (T) inst;
return (T)inst;
}
/**
* load class from class binary files.
* Most likely all the interceptor implementations should be loaded by this.
*
* @param className interceptor class name.
* @param className interceptor class name.
* @param targetClassLoader the classloader, which should load the interceptor.
* @param <T>
* @return interceptor instance.
......@@ -82,7 +85,7 @@ public class InterceptorInstanceLoader {
* @throws InstantiationException
*/
private static <T> T loadBinary(String className,
ClassLoader targetClassLoader) throws InvocationTargetException, IllegalAccessException, InstantiationException {
ClassLoader targetClassLoader) throws InvocationTargetException, IllegalAccessException, InstantiationException {
String path = "/" + className.replace('.', '/').concat(".class");
byte[] data = null;
BufferedInputStream is = null;
......@@ -122,21 +125,21 @@ public class InterceptorInstanceLoader {
}
defineClassMethod.setAccessible(true);
logger.debug("load binary code of {} to classloader {}", className, targetClassLoader);
Class<?> type = (Class<?>) defineClassMethod.invoke(targetClassLoader, className, data, 0, data.length, null);
return (T) type.newInstance();
Class<?> type = (Class<?>)defineClassMethod.invoke(targetClassLoader, className, data, 0, data.length, null);
return (T)type.newInstance();
}
/**
* Find loaded class in the current classloader.
* Just in case some classes have already been loaded for some reason.
*
* @param className interceptor class name.
* @param className interceptor class name.
* @param targetClassLoader the classloader, which should load the interceptor.
* @param <T>
* @return interceptor instance.
*/
private static <T> T findLoadedClass(String className,
ClassLoader targetClassLoader) throws InvocationTargetException, IllegalAccessException, InstantiationException {
ClassLoader targetClassLoader) throws InvocationTargetException, IllegalAccessException, InstantiationException {
Method defineClassMethod = null;
Class<?> targetClassLoaderType = targetClassLoader.getClass();
while (defineClassMethod == null && targetClassLoaderType != null) {
......@@ -147,10 +150,10 @@ public class InterceptorInstanceLoader {
}
}
defineClassMethod.setAccessible(true);
Class<?> type = (Class<?>) defineClassMethod.invoke(targetClassLoader, className);
Class<?> type = (Class<?>)defineClassMethod.invoke(targetClassLoader, className);
if (type == null) {
return null;
}
return (T) type.newInstance();
return (T)type.newInstance();
}
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册