import java.io.*;
import java.util.*;
import java.util.regex.*;
public class PerformanceAnalyzer {
public static void main(String[] args) {
try {
// Define directories
File beforeDir = new File("before");
File afterDir = new File("after");
File reportsDir = new File("reports");
// Create reports directory if it doesn't exist
reportsDir.mkdirs();
System.out.println("=== WebLogic Performance Analyzer ===");
// Extract performance data
List beforeControllerEntries = new ArrayList<>();
List beforeTokenEntries = new ArrayList<>();
List afterControllerEntries = new ArrayList<>();
List afterTokenEntries = new ArrayList<>();
System.out.println("\nProcessing BEFORE logs...");
processLogs(beforeDir, beforeControllerEntries, beforeTokenEntries);
System.out.println("\nProcessing AFTER logs...");
processLogs(afterDir, afterControllerEntries, afterTokenEntries);
// Generate reports
generateControllerReport(beforeControllerEntries, afterControllerEntries,
new File(reportsDir, "controller-methods-report.csv"));
generateTokenReport(beforeTokenEntries, afterTokenEntries,
new File(reportsDir, "token-execution-report.csv"));
// Generate summary report
generateSummaryReport(beforeControllerEntries, afterControllerEntries,
beforeTokenEntries, afterTokenEntries,
new File(reportsDir, "performance-summary.csv"));
System.out.println("\nAnalysis complete! Reports available in: " + reportsDir.getAbsolutePath());
} catch (Exception e) {
System.err.println("Error during analysis: " + e.getMessage());
e.printStackTrace();
}
}
private static void processLogs(File directory, List controllerEntries,
List tokenEntries) throws IOException {
// Process each log file in the directory
File[] files = directory.listFiles((dir, name) -> name.endsWith(".txt"));
if (files == null || files.length == 0) {
System.out.println(" No files found in directory!");
return;
}
for (File file : files) {
System.out.println(" Processing file: " + file.getName());
int controllerTimingsFound = 0;
int tokenTimingsFound = 0;
try (BufferedReader reader = new BufferedReader(new FileReader(file))) {
String line;
while ((line = reader.readLine()) != null) {
// Extract controller method timing
if (line.contains("*|*Time taken for*|*") && line.contains("*|*is*|*") && line.contains("*|*ms")) {
// Pattern: *|*Time taken for*|*Controller.method*|*is*|*time*|*ms
Pattern pattern = Pattern.compile("\\*\\|\\*Time taken for\\*\\|\\*(.*?)\\.(.*?)\\*\\|\\*is\\*\\|\\*(\\d+)\\*\\|\\*ms");
Matcher matcher = pattern.matcher(line);
if (matcher.find()) {
String controller = matcher.group(1);
String method = matcher.group(2);
int executionTime = Integer.parseInt(matcher.group(3));
// Extract timestamp
Pattern timestampPattern = Pattern.compile("(\\d{4}-\\d{2}-\\d{2} \\d{2}:\\d{2}:\\d{2},\\d{3})");
Matcher timestampMatcher = timestampPattern.matcher(line);
String timestamp = timestampMatcher.find() ? timestampMatcher.group(1) : "unknown";
// Extract thread info
Pattern threadPattern = Pattern.compile("Thread\\[\\[(ACTIVE|STANDBY)\\] ExecuteThread: '(\\d+)'");
Matcher threadMatcher = threadPattern.matcher(line);
String threadState = "unknown";
String threadId = "unknown";
if (threadMatcher.find()) {
threadState = threadMatcher.group(1);
threadId = threadMatcher.group(2);
}
ControllerEntry entry = new ControllerEntry();
entry.timestamp = timestamp;
entry.controller = controller;
entry.method = method;
entry.executionTime = executionTime;
entry.threadState = threadState;
entry.threadId = threadId;
entry.sourceFile = file.getName();
controllerEntries.add(entry);
controllerTimingsFound++;
}
}
// Extract token execution time
if (line.contains("Token execution time in(ms)")) {
// Pattern: Token execution time in(ms) [token-id] [time]
Pattern pattern = Pattern.compile("Token execution time in\\(ms\\) ([a-f0-9-]+)(?: (\\d+))?");
Matcher matcher = pattern.matcher(line);
if (matcher.find()) {
String tokenId = matcher.group(1);
String timeStr = matcher.groupCount() > 1 ? matcher.group(2) : null;
// If time is not directly after token ID, try to find it elsewhere in the line
int executionTime = 0;
if (timeStr != null) {
try {
executionTime = Integer.parseInt(timeStr);
} catch (NumberFormatException e) {
// Ignore and try to find elsewhere
}
}
if (executionTime == 0) {
// Try to find a number at the end of the line
Pattern numPattern = Pattern.compile("(\\d+)$");
Matcher numMatcher = numPattern.matcher(line);
if (numMatcher.find()) {
executionTime = Integer.parseInt(numMatcher.group(1));
}
}
// Extract timestamp
Pattern timestampPattern = Pattern.compile("(\\d{4}-\\d{2}-\\d{2} \\d{2}:\\d{2}:\\d{2},\\d{3})");
Matcher timestampMatcher = timestampPattern.matcher(line);
String timestamp = timestampMatcher.find() ? timestampMatcher.group(1) : "unknown";
// Extract thread info
Pattern threadPattern = Pattern.compile("Thread\\[\\[(ACTIVE|STANDBY)\\] ExecuteThread: '(\\d+)'");
Matcher threadMatcher = threadPattern.matcher(line);
String threadState = "unknown";
String threadId = "unknown";
if (threadMatcher.find()) {
threadState = threadMatcher.group(1);
threadId = threadMatcher.group(2);
}
TokenEntry entry = new TokenEntry();
entry.timestamp = timestamp;
entry.tokenId = tokenId;
entry.executionTime = executionTime;
entry.threadState = threadState;
entry.threadId = threadId;
entry.sourceFile = file.getName();
tokenEntries.add(entry);
tokenTimingsFound++;
}
}
}
}
System.out.println(" Controller method timings found: " + controllerTimingsFound);
System.out.println(" Token execution timings found: " + tokenTimingsFound);
}
System.out.println(" Total controller timings found: " + controllerEntries.size());
System.out.println(" Total token timings found: " + tokenEntries.size());
}
private static void generateControllerReport(List beforeEntries, List afterEntries,
File outputFile) throws IOException {
System.out.println("\nGenerating controller methods report...");
// Group entries by controller and method
Map> beforeGroups = groupControllerEntries(beforeEntries);
Map> afterGroups = groupControllerEntries(afterEntries);
// Get all unique keys
Set allKeys = new HashSet<>(beforeGroups.keySet());
allKeys.addAll(afterGroups.keySet());
List sortedKeys = new ArrayList<>(allKeys);
Collections.sort(sortedKeys);
try (PrintWriter writer = new PrintWriter(new FileWriter(outputFile))) {
// Write CSV header
writer.println("Controller,Method,SamplesBefore,SamplesAfter,AvgBefore(ms),AvgAfter(ms),Improvement(%)");
for (String key : sortedKeys) {
String[] parts = key.split("\\|");
String controller = parts[0];
String method = parts[1];
List beforeMethodEntries = beforeGroups.getOrDefault(key, Collections.emptyList());
List afterMethodEntries = afterGroups.getOrDefault(key, Collections.emptyList());
// Only include in report if we have data in both periods
if (!beforeMethodEntries.isEmpty() && !afterMethodEntries.isEmpty()) {
double beforeAvg = calculateAverage(beforeMethodEntries);
double afterAvg = calculateAverage(afterMethodEntries);
double improvement = 0;
if (beforeAvg > 0) {
improvement = ((beforeAvg - afterAvg) / beforeAvg) * 100;
}
writer.printf("%s,%s,%d,%d,%.2f,%.2f,%.2f%n",
controller, method,
beforeMethodEntries.size(), afterMethodEntries.size(),
beforeAvg, afterAvg, improvement);
}
}
}
System.out.println(" Report saved to: " + outputFile.getAbsolutePath());
}
private static void generateTokenReport(List beforeEntries, List afterEntries,
File outputFile) throws IOException {
System.out.println("\nGenerating token execution report...");
// Calculate statistics
double beforeAvg = calculateTokenAverage(beforeEntries);
double afterAvg = calculateTokenAverage(afterEntries);
double improvement = 0;
if (beforeAvg > 0) {
improvement = ((beforeAvg - afterAvg) / beforeAvg) * 100;
}
try (PrintWriter writer = new PrintWriter(new FileWriter(outputFile))) {
// Write CSV header
writer.println("Metric,Before,After,Improvement(%)");
writer.printf("Token Count,%d,%d,N/A%n", beforeEntries.size(), afterEntries.size());
writer.printf("Average Execution Time (ms),%.2f,%.2f,%.2f%n", beforeAvg, afterAvg, improvement);
// Add ACTIVE vs STANDBY thread analysis
Map> beforeByState = groupTokenEntriesByState(beforeEntries);
Map> afterByState = groupTokenEntriesByState(afterEntries);
for (String state : new String[]{"ACTIVE", "STANDBY"}) {
double beforeStateAvg = calculateTokenAverage(beforeByState.getOrDefault(state, Collections.emptyList()));
double afterStateAvg = calculateTokenAverage(afterByState.getOrDefault(state, Collections.emptyList()));
double stateImprovement = 0;
if (beforeStateAvg > 0) {
stateImprovement = ((beforeStateAvg - afterStateAvg) / beforeStateAvg) * 100;
}
writer.printf("%s Thread Avg (ms),%.2f,%.2f,%.2f%n",
state, beforeStateAvg, afterStateAvg, stateImprovement);
}
}
System.out.println(" Report saved to: " + outputFile.getAbsolutePath());
}
private static void generateSummaryReport(List beforeControllerEntries,
List afterControllerEntries,
List beforeTokenEntries,
List afterTokenEntries,
File outputFile) throws IOException {
System.out.println("\nGenerating performance summary report...");
// Calculate controller statistics
double beforeControllerAvg = calculateAverage(beforeControllerEntries);
double afterControllerAvg = calculateAverage(afterControllerEntries);
double controllerImprovement = 0;
if (beforeControllerAvg > 0) {
controllerImprovement = ((beforeControllerAvg - afterControllerAvg) / beforeControllerAvg) * 100;
}
// Calculate token statistics
double beforeTokenAvg = calculateTokenAverage(beforeTokenEntries);
double afterTokenAvg = calculateTokenAverage(afterTokenEntries);
double tokenImprovement = 0;
if (beforeTokenAvg > 0) {
tokenImprovement = ((beforeTokenAvg - afterTokenAvg) / beforeTokenAvg) * 100;
}
// Get top performers (most improved controller methods)
List topImproved = getTopImprovedMethods(beforeControllerEntries, afterControllerEntries, 5);
try (PrintWriter writer = new PrintWriter(new FileWriter(outputFile))) {
// Write CSV header
writer.println("WebLogic Performance Improvement Analysis");
writer.println();
writer.println("Overall Performance Metrics");
writer.println("Metric,Before,After,Improvement(%)");
writer.printf("Controller Method Avg (ms),%.2f,%.2f,%.2f%n",
beforeControllerAvg, afterControllerAvg, controllerImprovement);
writer.printf("Token Execution Avg (ms),%.2f,%.2f,%.2f%n",
beforeTokenAvg, afterTokenAvg, tokenImprovement);
writer.println();
writer.println("Top 5 Most Improved Controller Methods");
writer.println("Controller,Method,Before(ms),After(ms),Improvement(%)");
for (PerformanceResult result : topImproved) {
writer.printf("%s,%s,%.2f,%.2f,%.2f%n",
result.controller, result.method,
result.beforeAvg, result.afterAvg, result.improvement);
}
}
System.out.println(" Summary report saved to: " + outputFile.getAbsolutePath());
}
private static Map> groupControllerEntries(List entries) {
Map> groups = new HashMap<>();
for (ControllerEntry entry : entries) {
String key = entry.controller + "|" + entry.method;
groups.computeIfAbsent(key, k -> new ArrayList<>()).add(entry);
}
return groups;
}
private static Map> groupTokenEntriesByState(List entries) {
Map> groups = new HashMap<>();
for (TokenEntry entry : entries) {
groups.computeIfAbsent(entry.threadState, k -> new ArrayList<>()).add(entry);
}
return groups;
}
private static double calculateAverage(List entries) {
if (entries.isEmpty()) {
return 0;
}
long sum = 0;
for (ControllerEntry entry : entries) {
sum += entry.executionTime;
}
return (double) sum / entries.size();
}
private static double calculateTokenAverage(List entries) {
if (entries.isEmpty()) {
return 0;
}
long sum = 0;
for (TokenEntry entry : entries) {
sum += entry.executionTime;
}
return (double) sum / entries.size();
}
private static List getTopImprovedMethods(
List beforeEntries, List afterEntries, int limit) {
Map> beforeGroups = groupControllerEntries(beforeEntries);
Map> afterGroups = groupControllerEntries(afterEntries);
List results = new ArrayList<>();
for (String key : beforeGroups.keySet()) {
if (afterGroups.containsKey(key)) {
String[] parts = key.split("\\|");
String controller = parts[0];
String method = parts[1];
double beforeAvg = calculateAverage(beforeGroups.get(key));
double afterAvg = calculateAverage(afterGroups.get(key));
if (beforeAvg > 0 && afterAvg > 0) {
double improvement = ((beforeAvg - afterAvg) / beforeAvg) * 100;
PerformanceResult result = new PerformanceResult();
result.controller = controller;
result.method = method;
result.beforeAvg = beforeAvg;
result.afterAvg = afterAvg;
result.improvement = improvement;
results.add(result);
}
}
}
// Sort by improvement (descending)
results.sort((a, b) -> Double.compare(b.improvement, a.improvement));
// Return top N
return results.size() <= limit ? results : results.subList(0, limit);
}
static class ControllerEntry {
String timestamp;
String controller;
String method;
int executionTime;
String threadState;
String threadId;
String sourceFile;
}
static class TokenEntry {
String timestamp;
String tokenId;
int executionTime;
String threadState;
String threadId;
String sourceFile;
}
static class PerformanceResult {
String controller;
String method;
double beforeAvg;
double afterAvg;
double improvement;
}
}