Skip to content

Commit f521d6b

Browse files
committed
[UPDATE] Refactor code structure
1 parent 59cd1f4 commit f521d6b

File tree

4 files changed

+124
-76
lines changed

4 files changed

+124
-76
lines changed

.gitignore

+1
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
/.vscode/
33
/output/
44
/.settings/
5+
/.idea/
56

67
*.log
78

src/main/java/ca/polymtl/gigl/moose/kavehshahedi/bbi/FunctionEntryAgent.java

+31-52
Original file line numberDiff line numberDiff line change
@@ -5,24 +5,19 @@
55
import net.bytebuddy.description.method.MethodDescription;
66
import net.bytebuddy.description.type.TypeDescription;
77
import net.bytebuddy.matcher.ElementMatcher;
8-
import net.bytebuddy.matcher.ElementMatchers;
98

109
import java.io.File;
1110
import java.io.FileInputStream;
1211
import java.io.IOException;
1312
import java.io.InputStreamReader;
1413
import java.lang.instrument.Instrumentation;
15-
import java.util.ArrayList;
16-
import java.util.List;
1714
import java.util.Set;
1815

1916
import org.apache.logging.log4j.Logger;
2017
import org.apache.logging.log4j.core.LoggerContext;
21-
import org.apache.logging.log4j.core.config.LoggerConfig;
2218
import org.yaml.snakeyaml.LoaderOptions;
2319
import org.yaml.snakeyaml.Yaml;
2420
import org.yaml.snakeyaml.constructor.Constructor;
25-
import org.apache.logging.log4j.Level;
2621
import org.apache.logging.log4j.LogManager;
2722

2823
import ca.polymtl.gigl.moose.kavehshahedi.bbi.helpers.MethodMatcherHelper;
@@ -32,7 +27,7 @@ public class FunctionEntryAgent {
3227

3328
public static Logger logger;
3429

35-
public static boolean onlyCheckVisited = false;
30+
public static Configuration config;
3631

3732
public static final long TIME_OFFSET;
3833
static {
@@ -41,74 +36,58 @@ public class FunctionEntryAgent {
4136
TIME_OFFSET = (currentTimeMillis * 1_000_000) - currentNanoTime;
4237
}
4338

44-
public static void premain(String args, Instrumentation inst) throws SecurityException, IOException {
45-
Configuration config = new Configuration(new Configuration.Logging("fine", "logs.log"),
46-
new Configuration.Instrumentation(
47-
"", new Configuration.Instrumentation.TargetMethods(new ArrayList<>(), new ArrayList<>())));
39+
public static void premain(String args, Instrumentation inst) {
40+
config = new Configuration();
4841

49-
String options[];
50-
if (args != null && args.length() > 0) {
42+
String[] options;
43+
if (args != null && !args.isEmpty()) {
5144
options = args.split(",");
52-
if (options.length > 0) {
53-
for (String option : options) {
54-
if (option.contains("=")) {
55-
String key = option.split("=")[0];
56-
String value = option.split("=")[1];
57-
58-
switch (key) {
59-
case "config":
60-
Constructor constructor = new Constructor(Configuration.class, new LoaderOptions());
61-
Yaml yaml = new Yaml(constructor);
62-
try (InputStreamReader reader = new InputStreamReader(
63-
new FileInputStream(new File(value)))) {
45+
for (String option : options) {
46+
if (option.contains("=")) {
47+
String key = option.split("=")[0];
48+
String value = option.split("=")[1];
49+
50+
switch (key) {
51+
case "config":
52+
Constructor constructor = new Constructor(Configuration.class, new LoaderOptions());
53+
Yaml yaml = new Yaml(constructor);
54+
try (InputStreamReader reader = new InputStreamReader(
55+
new FileInputStream(new File(value)))) {
56+
try {
6457
config = yaml.load(reader);
65-
} catch (IOException e) {
66-
System.err.println("Error reading the configuration file");
58+
} catch (Exception e) {
59+
System.err.println("Error while parsing the configuration file");
6760
}
61+
} catch (IOException e) {
62+
System.err.println("Error while reading the configuration file");
63+
}
6864

69-
break;
70-
default:
71-
break;
72-
}
65+
break;
66+
default:
67+
break;
7368
}
7469
}
7570
}
7671
}
7772

7873
configureLoggerName(config.getLogging());
7974

80-
ElementMatcher.Junction<TypeDescription> targetPackageMatcher = ElementMatchers.any();
81-
if (!config.getInstrumentation().getTargetPackage().isEmpty()
82-
&& !config.getInstrumentation().getTargetPackage().equals("*")) {
83-
targetPackageMatcher = ElementMatchers.nameStartsWith(config.getInstrumentation().getTargetPackage());
84-
}
85-
86-
// Exclude the agent class from instrumentation (along with logging and other)
87-
targetPackageMatcher = targetPackageMatcher
88-
.and(ElementMatchers.not(ElementMatchers.nameStartsWith(FunctionEntryAgent.class.getPackageName())));
89-
targetPackageMatcher = targetPackageMatcher
90-
.and(ElementMatchers.not(ElementMatchers.nameStartsWith("org.apache.logging.log4j")));
75+
ElementMatcher.Junction<TypeDescription> targetPackageMatcher = MethodMatcherHelper.createTargetPackageMatcher(config.getInstrumentation());
76+
ElementMatcher.Junction<MethodDescription> methodMatcher = MethodMatcherHelper.createMethodMatcher(config.getInstrumentation());
9177

92-
List<String> instrumentMethodSignatures = config.getInstrumentation().getTargetMethods().getInstrument();
93-
List<String> ignoreMethodSignatures = config.getInstrumentation().getTargetMethods().getIgnore();
94-
95-
ElementMatcher.Junction<MethodDescription> methodMatchers = MethodMatcherHelper
96-
.createMethodMatcher(instrumentMethodSignatures, ignoreMethodSignatures);
78+
System.out.println(config);
9779

9880
new AgentBuilder.Default()
9981
.type(targetPackageMatcher)
10082
.transform(new AgentBuilder.Transformer.ForAdvice()
101-
.advice(methodMatchers, MethodExecutionTime.class.getName()))
83+
.advice(methodMatcher, MethodExecutionTime.class.getName()))
10284
.installOn(inst);
10385

10486
System.out.println("-".repeat(20));
10587
}
10688

10789
public static void configureLoggerName(Configuration.Logging loggingInfo) {
10890
String logFileName = loggingInfo.getFile();
109-
if (logFileName == null || logFileName.isEmpty())
110-
logFileName = "logs.log";
111-
11291
System.setProperty("logFilename", logFileName);
11392

11493
LoggerContext ctx = (LoggerContext) LogManager.getContext(false);
@@ -126,7 +105,7 @@ public static class MethodExecutionTime {
126105

127106
@Advice.OnMethodEnter
128107
static void enter(@Advice.Origin String methodSignature) {
129-
if (onlyCheckVisited) {
108+
if (config.getInstrumentation().isOnlyCheckVisited()) {
130109
if (!visitedMethods.contains(methodSignature)) {
131110
visitedMethods.add(methodSignature);
132111
logTime(methodSignature, "ENTER");
@@ -138,7 +117,7 @@ static void enter(@Advice.Origin String methodSignature) {
138117

139118
@Advice.OnMethodExit
140119
static void exit(@Advice.Origin String methodSignature) {
141-
if (onlyCheckVisited)
120+
if (config.getInstrumentation().isOnlyCheckVisited())
142121
return;
143122

144123
logTime(methodSignature, "EXIT");

src/main/java/ca/polymtl/gigl/moose/kavehshahedi/bbi/helpers/MethodMatcherHelper.java

+32-12
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
package ca.polymtl.gigl.moose.kavehshahedi.bbi.helpers;
22

3+
import ca.polymtl.gigl.moose.kavehshahedi.bbi.FunctionEntryAgent;
4+
import ca.polymtl.gigl.moose.kavehshahedi.bbi.models.Configuration;
35
import net.bytebuddy.description.method.MethodDescription;
6+
import net.bytebuddy.description.type.TypeDescription;
47
import net.bytebuddy.matcher.ElementMatcher;
58
import net.bytebuddy.matcher.ElementMatchers;
69

@@ -9,11 +12,12 @@
912

1013
public class MethodMatcherHelper {
1114

12-
public static ElementMatcher.Junction<MethodDescription> createMethodMatcher(
13-
List<String> instrumentMethodSignatures, List<String> ignoreMethodSignatures) {
15+
public static ElementMatcher.Junction<MethodDescription> createMethodMatcher(Configuration.Instrumentation instrumentation) {
16+
List<String> instrumentMethodSignatures = instrumentation.getTargetMethods().getInstrument();
17+
List<String> ignoreMethodSignatures = instrumentation.getTargetMethods().getIgnore();
1418

1519
ElementMatcher.Junction<MethodDescription> methodMatchers = ElementMatchers.none();
16-
if (instrumentMethodSignatures.size() == 0)
20+
if (instrumentMethodSignatures.isEmpty())
1721
methodMatchers = ElementMatchers.isMethod();
1822

1923
for (String signature : instrumentMethodSignatures) {
@@ -33,6 +37,22 @@ public static ElementMatcher.Junction<MethodDescription> createMethodMatcher(
3337
return methodMatchers;
3438
}
3539

40+
public static ElementMatcher.Junction<TypeDescription> createTargetPackageMatcher(Configuration.Instrumentation instrumentation) {
41+
ElementMatcher.Junction<TypeDescription> targetPackageMatcher = ElementMatchers.any();
42+
if (!instrumentation.getTargetPackage().isEmpty()
43+
&& !instrumentation.getTargetPackage().equals("*")) {
44+
targetPackageMatcher = ElementMatchers.nameStartsWith(instrumentation.getTargetPackage());
45+
}
46+
47+
// Exclude the agent class from instrumentation (along with logging and other)
48+
targetPackageMatcher = targetPackageMatcher
49+
.and(ElementMatchers.not(ElementMatchers.nameStartsWith(FunctionEntryAgent.class.getPackageName())));
50+
targetPackageMatcher = targetPackageMatcher
51+
.and(ElementMatchers.not(ElementMatchers.nameStartsWith("org.apache.logging.log4j")));
52+
53+
return targetPackageMatcher;
54+
}
55+
3656
private static ElementMatcher.Junction<MethodDescription> createMatcherFromSignature(
3757
MethodSignature methodSignature) {
3858
ElementMatcher.Junction<MethodDescription> matcher = ElementMatchers.named(methodSignature.getMethodName())
@@ -62,15 +82,15 @@ private static ElementMatcher.Junction<MethodDescription> createMatcherFromSigna
6282
return matcher;
6383
}
6484

65-
static class MethodSignature {
66-
private String methodName;
67-
private String declaringClass;
68-
private int numArguments;
69-
private boolean isStatic;
70-
private boolean isPublic;
71-
private boolean isPrivate;
72-
private boolean isProtected;
73-
private boolean isPackagePrivate;
85+
private static class MethodSignature {
86+
private final String methodName;
87+
private final String declaringClass;
88+
private final int numArguments;
89+
private final boolean isStatic;
90+
private final boolean isPublic;
91+
private final boolean isPrivate;
92+
private final boolean isProtected;
93+
private final boolean isPackagePrivate;
7494

7595
public MethodSignature(String methodName, String declaringClass, int numArguments, boolean isStatic,
7696
boolean isPublic,

src/main/java/ca/polymtl/gigl/moose/kavehshahedi/bbi/models/Configuration.java

+60-12
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,11 @@
44
import java.util.List;
55

66
public class Configuration {
7+
8+
// Constants
9+
public static final String DEFAULT_LOGGING_LEVEL = "INFO";
10+
public static final String DEFAULT_LOG_FILE = "app.log";
11+
712
private Logging logging = new Logging();
813
private Instrumentation instrumentation = new Instrumentation();
914

@@ -32,55 +37,67 @@ public void setInstrumentation(Instrumentation instrumentation) {
3237
this.instrumentation = instrumentation != null ? instrumentation : new Instrumentation();
3338
}
3439

40+
@Override
41+
public String toString() {
42+
return "Instrumentation Configuration:\n\tLogging:\n" + logging.toString() + "\n\tInstrumentation:\n" + instrumentation.toString();
43+
}
44+
3545
public static class Logging {
36-
private String level = "INFO"; // Default logging level
37-
private String file = "app.log"; // Default log file
46+
private String level = DEFAULT_LOGGING_LEVEL;
47+
private String file = DEFAULT_LOG_FILE;
3848

3949
public Logging() {
4050
}
4151

4252
public Logging(String level, String file) {
43-
this.level = level != null ? level : "INFO";
44-
this.file = file != null ? file : "app.log";
53+
this.level = level != null ? level : DEFAULT_LOGGING_LEVEL;
54+
this.file = file != null ? file : DEFAULT_LOG_FILE;
4555
}
4656

4757
// Getters and setters
4858
public String getLevel() {
49-
return level != null ? level : "INFO";
59+
return level != null ? level : DEFAULT_LOGGING_LEVEL;
5060
}
5161

5262
public void setLevel(String level) {
53-
this.level = level != null ? level : "INFO";
63+
this.level = level != null ? level : DEFAULT_LOGGING_LEVEL;
5464
}
5565

5666
public String getFile() {
57-
return file != null ? file : "app.log";
67+
return file != null ? file : DEFAULT_LOG_FILE;
5868
}
5969

6070
public void setFile(String file) {
61-
this.file = file != null ? file : "app.log";
71+
this.file = file != null ? file : DEFAULT_LOG_FILE;
72+
}
73+
74+
@Override
75+
public String toString() {
76+
return "\t\tLevel: " + level + "\n\t\tFile: " + file;
6277
}
6378
}
6479

6580
public static class Instrumentation {
66-
private String targetPackage = ""; // Default target package
81+
private String targetPackage = "*"; // Default target package
6782
private TargetMethods targetMethods = new TargetMethods();
83+
private boolean onlyCheckVisited = false;
6884

6985
public Instrumentation() {
7086
}
7187

72-
public Instrumentation(String targetPackage, TargetMethods targetMethods) {
88+
public Instrumentation(String targetPackage, TargetMethods targetMethods, boolean checkOnlyVisited) {
7389
this.targetPackage = targetPackage != null ? targetPackage : "";
7490
this.targetMethods = targetMethods != null ? targetMethods : new TargetMethods();
91+
this.onlyCheckVisited = checkOnlyVisited;
7592
}
7693

7794
// Getters and setters
7895
public String getTargetPackage() {
79-
return targetPackage != null ? targetPackage : "";
96+
return targetPackage != null ? targetPackage : "*";
8097
}
8198

8299
public void setTargetPackage(String targetPackage) {
83-
this.targetPackage = targetPackage != null ? targetPackage : "";
100+
this.targetPackage = targetPackage != null ? targetPackage : "*";
84101
}
85102

86103
public TargetMethods getTargetMethods() {
@@ -90,6 +107,19 @@ public TargetMethods getTargetMethods() {
90107
public void setTargetMethods(TargetMethods targetMethods) {
91108
this.targetMethods = targetMethods != null ? targetMethods : new TargetMethods();
92109
}
110+
111+
public boolean isOnlyCheckVisited() {
112+
return onlyCheckVisited;
113+
}
114+
115+
public void setOnlyCheckVisited(boolean onlyCheckVisited) {
116+
this.onlyCheckVisited = onlyCheckVisited;
117+
}
118+
119+
@Override
120+
public String toString() {
121+
return "\t\tTarget Package: " + targetPackage + "\n\t\tOnly Check Visited: " + onlyCheckVisited + "\n\t\tTarget Methods: " + targetMethods.toString();
122+
}
93123

94124
public static class TargetMethods {
95125
private List<String> instrument = Collections.emptyList(); // Default empty list
@@ -119,6 +149,24 @@ public List<String> getIgnore() {
119149
public void setIgnore(List<String> ignore) {
120150
this.ignore = ignore != null ? ignore : Collections.emptyList();
121151
}
152+
153+
@Override
154+
public String toString() {
155+
StringBuilder output = new StringBuilder();
156+
output.append("\n\t\t\tInstrument:");
157+
output.append(instrument.isEmpty() ? " *\n" : "\n");
158+
for (String method : instrument) {
159+
output.append("\t\t\t\t- ").append(method).append("\n");
160+
}
161+
162+
output.append("\t\t\tIgnore:");
163+
output.append(ignore.isEmpty() ? " N/A\n" : "\n");
164+
for (String method : ignore) {
165+
output.append("\t\t\t\t- ").append(method).append("\n");
166+
}
167+
168+
return output.toString().stripTrailing();
169+
}
122170
}
123171
}
124172
}

0 commit comments

Comments
 (0)