some more cleanup
This commit is contained in:
parent
ec23bbd64c
commit
2a08749384
2 changed files with 77 additions and 58 deletions
|
|
@ -2,33 +2,42 @@ package perfix;
|
||||||
|
|
||||||
import javassist.*;
|
import javassist.*;
|
||||||
|
|
||||||
import java.io.BufferedReader;
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStreamReader;
|
|
||||||
import java.io.PrintStream;
|
|
||||||
import java.lang.instrument.Instrumentation;
|
import java.lang.instrument.Instrumentation;
|
||||||
import java.net.ServerSocket;
|
|
||||||
import java.net.Socket;
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
import static java.util.Arrays.asList;
|
||||||
|
|
||||||
public class Agent {
|
public class Agent {
|
||||||
|
|
||||||
public static final String MESSAGE = "Perfix agent active";
|
private static final String PORT_PROPERTY = "perfix.port";
|
||||||
|
private static final String INCLUDES_PROPERTY = "perfix.includes";
|
||||||
|
|
||||||
|
private static final String DEFAULT_PORT = "2048";
|
||||||
|
private static final String MESSAGE = "Perfix agent active";
|
||||||
|
|
||||||
|
private static final String PERFIX_METHOD_CLASS = "perfix.Method";
|
||||||
|
|
||||||
public static void premain(String agentArgs, Instrumentation inst) {
|
public static void premain(String agentArgs, Instrumentation inst) {
|
||||||
System.out.println(MESSAGE);
|
System.out.println(MESSAGE);
|
||||||
|
|
||||||
startListeningOnSocket();
|
int port = Integer.parseInt(System.getProperty(PORT_PROPERTY, DEFAULT_PORT));
|
||||||
|
|
||||||
instrumentCode(inst);
|
instrumentCode(inst);
|
||||||
|
|
||||||
|
new Server().startListeningOnSocket(port);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void instrumentCode(Instrumentation inst) {
|
private static void instrumentCode(Instrumentation inst) {
|
||||||
List<String> includes = determineIncludes();
|
List<String> includes = determineIncludes();
|
||||||
|
|
||||||
inst.addTransformer((classLoader, resource, aClass, protectionDomain, uninstrumentedByteCode) -> {
|
inst.addTransformer((classLoader, resource, aClass, protectionDomain, uninstrumentedByteCode)
|
||||||
|
-> createByteCode(includes, resource, uninstrumentedByteCode));
|
||||||
|
}
|
||||||
|
|
||||||
|
private static byte[] createByteCode(List<String> includes, String resource, byte[] uninstrumentedByteCode) {
|
||||||
if (!isInnerClass(resource) && shouldInclude(resource, includes)) {
|
if (!isInnerClass(resource) && shouldInclude(resource, includes)) {
|
||||||
try {
|
try {
|
||||||
byte[] instrumentedBytecode = instrumentMethod(resource);
|
byte[] instrumentedBytecode = instrumentMethod(resource);
|
||||||
|
|
@ -40,52 +49,12 @@ public class Agent {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return uninstrumentedByteCode;
|
return uninstrumentedByteCode;
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void startListeningOnSocket() {
|
|
||||||
try {
|
|
||||||
ServerSocket serverSocket = new ServerSocket(2048);
|
|
||||||
new Thread(() -> {
|
|
||||||
for (; ; ) {
|
|
||||||
try {
|
|
||||||
Socket client = serverSocket.accept();
|
|
||||||
|
|
||||||
PrintStream out = new PrintStream(client.getOutputStream());
|
|
||||||
out.println("press [enter] for report or [q and enter] to quit");
|
|
||||||
|
|
||||||
BufferedReader reader = new BufferedReader(new InputStreamReader(client.getInputStream()));
|
|
||||||
String line;
|
|
||||||
while ((line = reader.readLine()) != null) {
|
|
||||||
if (line.equals("q")) {
|
|
||||||
try {
|
|
||||||
client.close();
|
|
||||||
break;
|
|
||||||
} catch (IOException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
Registry.report(out);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (Exception e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}).start();
|
|
||||||
} catch (Exception e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static boolean isInnerClass(String resource) {
|
|
||||||
return resource.contains("$");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static byte[] instrumentMethod(String resource) throws
|
private static byte[] instrumentMethod(String resource) throws
|
||||||
NotFoundException, IOException, CannotCompileException {
|
NotFoundException, IOException, CannotCompileException {
|
||||||
ClassPool cp = ClassPool.getDefault();
|
ClassPool cp = ClassPool.getDefault();
|
||||||
CtClass methodClass = cp.get("perfix.Method");
|
CtClass methodClass = cp.get(PERFIX_METHOD_CLASS);
|
||||||
|
|
||||||
CtClass classToInstrument = cp.get(resource.replaceAll("/", "."));
|
CtClass classToInstrument = cp.get(resource.replaceAll("/", "."));
|
||||||
if (!classToInstrument.isInterface()) {
|
if (!classToInstrument.isInterface()) {
|
||||||
|
|
@ -111,7 +80,7 @@ public class Agent {
|
||||||
}
|
}
|
||||||
|
|
||||||
private static List<String> determineIncludes() {
|
private static List<String> determineIncludes() {
|
||||||
return new ArrayList<>(Arrays.asList(System.getProperty("perfix.includes").split(",")));
|
return new ArrayList<>(asList(System.getProperty(INCLUDES_PROPERTY).split(",")));
|
||||||
}
|
}
|
||||||
|
|
||||||
private static boolean shouldInclude(String resource, List<String> excludes) {
|
private static boolean shouldInclude(String resource, List<String> excludes) {
|
||||||
|
|
@ -124,6 +93,10 @@ public class Agent {
|
||||||
return included.get();
|
return included.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static boolean isInnerClass(String resource) {
|
||||||
|
return resource.contains("$");
|
||||||
|
}
|
||||||
|
|
||||||
static class BooleanWrapper {
|
static class BooleanWrapper {
|
||||||
boolean value;
|
boolean value;
|
||||||
|
|
||||||
|
|
|
||||||
46
src/main/java/perfix/Server.java
Normal file
46
src/main/java/perfix/Server.java
Normal file
|
|
@ -0,0 +1,46 @@
|
||||||
|
package perfix;
|
||||||
|
|
||||||
|
import java.io.BufferedReader;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStreamReader;
|
||||||
|
import java.io.PrintStream;
|
||||||
|
import java.net.ServerSocket;
|
||||||
|
import java.net.Socket;
|
||||||
|
|
||||||
|
public class Server {
|
||||||
|
void startListeningOnSocket(int port) {
|
||||||
|
try {
|
||||||
|
ServerSocket serverSocket = new ServerSocket(port);
|
||||||
|
new Thread(() -> {
|
||||||
|
for (; ; ) {
|
||||||
|
try {
|
||||||
|
Socket client = serverSocket.accept();
|
||||||
|
|
||||||
|
PrintStream out = new PrintStream(client.getOutputStream());
|
||||||
|
out.println("press [enter] for report or [q and enter] to quit");
|
||||||
|
|
||||||
|
BufferedReader reader = new BufferedReader(new InputStreamReader(client.getInputStream()));
|
||||||
|
String line;
|
||||||
|
while ((line = reader.readLine()) != null) {
|
||||||
|
if (line.equals("q")) {
|
||||||
|
try {
|
||||||
|
client.close();
|
||||||
|
break;
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
Registry.report(out);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}).start();
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
Loading…
Add table
Reference in a new issue