添加全方法监控的功能
This commit is contained in:
parent
f5acbaff87
commit
81a8aabc02
|
|
@ -1,12 +1,20 @@
|
|||
package com.ai.cloud.skywalking.agent;
|
||||
|
||||
import com.ai.cloud.skywalking.conf.Config;
|
||||
import com.ai.cloud.skywalking.conf.ConfigInitializer;
|
||||
import com.ai.cloud.skywalking.plugin.PluginBootstrap;
|
||||
import com.ai.cloud.skywalking.transformer.ClassTransformer;
|
||||
|
||||
import java.lang.instrument.Instrumentation;
|
||||
|
||||
public class SkywalkingAgent {
|
||||
|
||||
public static void premain(String agentArgs, Instrumentation inst) {
|
||||
ConfigInitializer.initialize();
|
||||
if (Config.SkyWalking.ALL_METHOD_MONITOR){
|
||||
inst.addTransformer(new ClassTransformer());
|
||||
}
|
||||
|
||||
PluginBootstrap bootstrap = new PluginBootstrap();
|
||||
bootstrap.start();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -44,6 +44,16 @@
|
|||
<version>1.0-Final</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.javassist</groupId>
|
||||
<artifactId>javassist</artifactId>
|
||||
<version>3.20.0-GA</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.google.code.gson</groupId>
|
||||
<artifactId>gson</artifactId>
|
||||
<version>2.7</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
<build>
|
||||
<plugins>
|
||||
|
|
|
|||
|
|
@ -12,6 +12,8 @@ public class Config {
|
|||
public static boolean AUTH_OVERRIDE = false;
|
||||
|
||||
public static String CHARSET = "UTF-8";
|
||||
|
||||
public static boolean ALL_METHOD_MONITOR = false;
|
||||
}
|
||||
|
||||
public static class BuriedPoint {
|
||||
|
|
|
|||
|
|
@ -0,0 +1,64 @@
|
|||
package com.ai.cloud.skywalking.transformer;
|
||||
|
||||
import com.ai.cloud.skywalking.logging.LogManager;
|
||||
import com.ai.cloud.skywalking.logging.Logger;
|
||||
import javassist.ClassPool;
|
||||
import javassist.CtClass;
|
||||
import javassist.CtMethod;
|
||||
|
||||
import java.lang.instrument.ClassFileTransformer;
|
||||
import java.lang.instrument.IllegalClassFormatException;
|
||||
import java.lang.reflect.Modifier;
|
||||
import java.security.ProtectionDomain;
|
||||
|
||||
public class ClassTransformer implements ClassFileTransformer {
|
||||
|
||||
private Logger logger = LogManager.getLogger(ClassTransformer.class);
|
||||
|
||||
@Override
|
||||
public byte[] transform(ClassLoader loader, String className, Class<?> classBeingRedefined, ProtectionDomain protectionDomain, byte[] classfileBuffer) throws IllegalClassFormatException {
|
||||
String interceptorPackage = System.getProperty("interceptor.package", "");
|
||||
if (interceptorPackage == null || interceptorPackage.length() == 0) {
|
||||
return classfileBuffer;
|
||||
}
|
||||
|
||||
if (!className.replaceAll("/", ".").startsWith(interceptorPackage)) {
|
||||
return classfileBuffer;
|
||||
}
|
||||
|
||||
try {
|
||||
ClassPool classPool = ClassPool.getDefault();
|
||||
CtClass ctClass = classPool.get(className.replaceAll("/", "."));
|
||||
|
||||
if (ctClass.isInterface()) {
|
||||
return classfileBuffer;
|
||||
}
|
||||
|
||||
CtMethod[] ctMethod = ctClass.getDeclaredMethods();
|
||||
for (CtMethod method : ctMethod) {
|
||||
if (Modifier.isStatic(method.getModifiers())) {
|
||||
continue;
|
||||
}
|
||||
|
||||
String methodName = method.getName();
|
||||
method.setName(methodName + "_skywalking_enhance");
|
||||
|
||||
CtMethod newMethod =
|
||||
new CtMethod(method.getReturnType(), methodName, method.getParameterTypes(),
|
||||
method.getDeclaringClass());
|
||||
newMethod.setBody("{" +
|
||||
MethodInterceptor.class.getName() + ".before($class,,$sig,$args,$0,\"" + methodName + "\");"
|
||||
+ "return " + methodName + "_skywalking_enhance($$);}");
|
||||
newMethod.addCatch("{ " + MethodInterceptor.class.getName() + ".handleException(e); throw e;}", classPool.get("java.lang.Throwable"), "e");
|
||||
newMethod.insertAfter("{" + MethodInterceptor.class.getName() + ".after($class,$type,$_);}", true);
|
||||
|
||||
ctClass.addMethod(newMethod);
|
||||
}
|
||||
return ctClass.toBytecode();
|
||||
} catch (Exception e) {
|
||||
logger.error("Failed to transform class" + className, e);
|
||||
return classfileBuffer;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,66 @@
|
|||
package com.ai.cloud.skywalking.transformer;
|
||||
|
||||
import com.ai.cloud.skywalking.api.IBuriedPointType;
|
||||
import com.ai.cloud.skywalking.invoke.monitor.LocalMethodInvokeMonitor;
|
||||
import com.ai.cloud.skywalking.model.Identification;
|
||||
import com.ai.cloud.skywalking.protocol.common.CallType;
|
||||
import com.google.gson.Gson;
|
||||
|
||||
public class MethodInterceptor {
|
||||
|
||||
|
||||
public void before(Class originClass, Class[] parametersType, Object[] allArgument, Object superCall, String methodName) {
|
||||
LocalMethodInvokeMonitor localMethodInvokeMonitor = new LocalMethodInvokeMonitor();
|
||||
Identification.IdentificationBuilder identificationBuilder = Identification.newBuilder();
|
||||
identificationBuilder.viewPoint(generateViewPoint(originClass, parametersType, methodName));
|
||||
appendingParameters(allArgument, identificationBuilder);
|
||||
identificationBuilder.spanType(new IBuriedPointType() {
|
||||
@Override
|
||||
public String getTypeName() {
|
||||
return "LOCAL";
|
||||
}
|
||||
|
||||
@Override
|
||||
public CallType getCallType() {
|
||||
return CallType.SYNC;
|
||||
}
|
||||
});
|
||||
|
||||
localMethodInvokeMonitor.beforeInvoke(identificationBuilder.build());
|
||||
|
||||
}
|
||||
|
||||
private void appendingParameters(Object[] allArgument, Identification.IdentificationBuilder identificationBuilder) {
|
||||
for (int i = 0; i < allArgument.length; i++) {
|
||||
try {
|
||||
identificationBuilder.appendParameter("P" + i, new Gson().toJson(allArgument[i]));
|
||||
} catch (Exception e) {
|
||||
// Do nothing
|
||||
} finally {
|
||||
identificationBuilder.appendParameter("P" + i, "Cannot convert parameter");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private String generateViewPoint(Class originClass, Class[] parametersType, String methodName) {
|
||||
StringBuilder viewPoint = new StringBuilder(originClass.getName() + "." + methodName + "(");
|
||||
for (Class parameterType : parametersType) {
|
||||
viewPoint.append(parameterType.getClass() + ",");
|
||||
}
|
||||
viewPoint.append(")");
|
||||
return viewPoint.toString();
|
||||
}
|
||||
|
||||
|
||||
public void handleException(Throwable e) {
|
||||
new LocalMethodInvokeMonitor().occurException(e);
|
||||
}
|
||||
|
||||
|
||||
public void after(Class originClass, Class resultType, Object result) {
|
||||
//TODO 需要把参数累加上去
|
||||
new LocalMethodInvokeMonitor().afterInvoke();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
package com.ai.cloud.skywalking.transformer;
|
||||
|
||||
public class StaticMethodInterceptor {
|
||||
|
||||
public void intercept(Class originClass, Object[] allArgument) {
|
||||
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue