some more cleanup

This commit is contained in:
Sander Hautvast 2018-04-06 16:56:13 +02:00
parent ec23bbd64c
commit 2a08749384
2 changed files with 77 additions and 58 deletions

View file

@ -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;

View 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();
}
}
}