-
Notifications
You must be signed in to change notification settings - Fork 3
Expand file tree
/
Copy pathApmAgent.java
More file actions
79 lines (69 loc) · 3.3 KB
/
ApmAgent.java
File metadata and controls
79 lines (69 loc) · 3.3 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
package org.greenleaf;
import javassist.ClassPool;
import javassist.CtClass;
import javassist.CtConstructor;
import javassist.CtMethod;
import javassist.LoaderClassPath;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.lang.instrument.ClassFileTransformer;
import java.lang.instrument.IllegalClassFormatException;
import java.lang.instrument.Instrumentation;
import java.security.ProtectionDomain;
public class ApmAgent implements ClassFileTransformer {
private static Logger logger = LoggerFactory.getLogger(ApmAgent.class);
@Override
public byte[] transform(ClassLoader loader, String className,
Class<?> classBeingRedefined, ProtectionDomain protectionDomain,
byte[] classfileBuffer) throws IllegalClassFormatException {
if (className.startsWith("java") || className.startsWith("sun") ||
!className.contains("greenleaf")) {
return null;
}
ClassPool pool = new ClassPool(true);
pool.appendClassPath(new LoaderClassPath(loader));
try {
CtClass cls = pool.makeClass(new ByteArrayInputStream(classfileBuffer));
CtConstructor[] ccs = cls.getDeclaredConstructors();
for (CtConstructor cc : ccs) {
String codeStrBefore = "System.out.println(\"This code is inserted before constructor " + className + "\");";
String codeStrAfter = "System.out.println(\"This code is inserted after constructor " + className + "\");";
cc.insertBeforeBody((codeStrBefore));
cc.insertAfter(codeStrAfter, true);
}
long startTime = System.currentTimeMillis();
System.out.println("time cost " + (System.currentTimeMillis() - startTime));
CtMethod[] methods = cls.getDeclaredMethods();
for (CtMethod method : methods) {
//插入本地变量
method.addLocalVariable("startTime", CtClass.longType);
String codeStrBefore = "startTime=System.currentTimeMillis();";
StringBuilder stringBuilder = new StringBuilder();
stringBuilder.append("System.out.println(")
.append("\"" + method.getName() + " time cost \"").append(" + (System.currentTimeMillis() - startTime) + \"毫秒\");");
String codeStrAfter = stringBuilder.toString();
System.out.println(codeStrBefore);
System.out.println(codeStrAfter);
method.insertBefore(codeStrBefore);
method.insertAfter(codeStrAfter);
}
File file = new File("./target/", cls.getSimpleName() + ".class");
try (FileOutputStream fileOutputStream = new FileOutputStream(file)) {
fileOutputStream.write(cls.toBytecode());
} catch (Exception e) {
e.printStackTrace();
}
return cls.toBytecode();
} catch (Exception e) {
logger.error("", e);
}
return null;
}
public static void premain(String agentArgs, Instrumentation inst) {
logger.info("premain exe args : {}" + agentArgs);
inst.addTransformer(new ApmAgent());
}
}