import java.io.*;
import java.nio.file.*;
import java.util.*;
import java.util.regex.*;
import java.util.stream.*;
public class LogAnalyzer {
public static void main(String[] args) {
try {
// Define directories
File beforeDir = new File("before");
File afterDir = new File("after");
File tempDir = new File("temp");
File reportsDir = new File("reports");
// Create temp and reports directories if they don't exist
tempDir.mkdirs();
reportsDir.mkdirs();
// Process before and after logs
System.out.println("Processing BEFORE logs...");
processLogs(beforeDir, new File(tempDir, "before"));
System.out.println("Processing AFTER logs...");
processLogs(afterDir, new File(tempDir, "after"));
// Extract timings
extractTimings(new File(tempDir, "before/controller-times.txt"),
new File(tempDir, "before-controller.csv"), "controller");
extractTimings(new File(tempDir, "before/init-times.txt"),
new File(tempDir, "before-init.csv"), "init");
extractTimings(new File(tempDir, "before/token-times.txt"),
new File(tempDir, "before-token.csv"), "token");
extractTimings(new File(tempDir, "after/controller-times.txt"),
new File(tempDir, "after-controller.csv"), "controller");
extractTimings(new File(tempDir, "after/init-times.txt"),
new File(tempDir, "after-init.csv"), "init");
extractTimings(new File(tempDir, "after/token-times.txt"),
new File(tempDir, "after-token.csv"), "token");
// Compare performance
comparePerformance(new File(tempDir, "before-controller.csv"),
new File(tempDir, "after-controller.csv"),
new File(reportsDir, "controller-comparison.csv"), "controller");
comparePerformance(new File(tempDir, "before-init.csv"),
new File(tempDir, "after-init.csv"),
new File(reportsDir, "init-comparison.csv"), "init");
comparePerformance(new File(tempDir, "before-token.csv"),
new File(tempDir, "after-token.csv"),
new File(reportsDir, "token-comparison.csv"), "token");
System.out.println("Analysis complete. Reports available in: " + reportsDir.getAbsolutePath());
} catch (Exception e) {
System.err.println("Error during analysis: " + e.getMessage());
e.printStackTrace();
}
}
private static void processLogs(File inputDir, File outputDir) throws IOException {
outputDir.mkdirs();
// Create files for different categories
File controllerTimesFile = new File(outputDir, "controller-times.txt");
File initTimesFile = new File(outputDir, "init-times.txt");
File tokenTimesFile = new File(outputDir, "token-times.txt");
// Create writers
try (PrintWriter controllerWriter = new PrintWriter(new FileWriter(controllerTimesFile));
PrintWriter initWriter = new PrintWriter(new FileWriter(initTimesFile));
PrintWriter tokenWriter = new PrintWriter(new FileWriter(tokenTimesFile))) {
// Process each log file
for (File logFile : inputDir.listFiles((dir, name) -> name.endsWith(".txt"))) {
System.out.println(" Processing " + logFile.getName());
try (BufferedReader reader = new BufferedReader(new FileReader(logFile))) {
String line;
while ((line = reader.readLine()) != null) {
// Extract controller method timings
if (line.contains("Time taken for") && line.contains("is") && line.contains("ms")) {
controllerWriter.println(line);
}
// Extract initialization timings
else if (line.contains("initialization completed in") && line.contains("ms")) {
initWriter.println(line);
}
// Extract token timings
else if (line.contains("Token execution time in(ms)")) {
tokenWriter.println(line);
}
}
}
}
}
}
private static void extractTimings(File categoryFile, File outputFile, String type) throws IOException {
if (!categoryFile.exists()) {
// Create empty file if the category file doesn't exist
try (PrintWriter writer = new PrintWriter(new FileWriter(outputFile))) {
if ("controller".equals(type)) {
writer.println("Controller,Method,Time");
} else if ("init".equals(type)) {
writer.println("InitTime");
} else if ("token".equals(type)) {
writer.println("TokenID,Time");
}
}
return;
}
try (PrintWriter writer = new PrintWriter(new FileWriter(outputFile));
BufferedReader reader = new BufferedReader(new FileReader(categoryFile))) {
// Write CSV header
if ("controller".equals(type)) {
writer.println("Controller,Method,Time");
} else if ("init".equals(type)) {
writer.println("InitTime");
} else if ("token".equals(type)) {
writer.println("TokenID,Time");
}
String line;
while ((line = reader.readLine()) != null) {
if ("controller".equals(type)) {
// Match controller method timing: Time taken for*|*Controller.method*|*is*|*time*|*ms
Pattern pattern = Pattern.compile("Time taken for\\*\\|\\*(.*?)\\.(.*?)\\*\\|\\*is\\*\\|\\*(.*?)\\*\\|\\*ms");
Matcher matcher = pattern.matcher(line);
if (matcher.find()) {
String controller = matcher.group(1);
String method = matcher.group(2);
String time = matcher.group(3);
writer.println(controller + "," + method + "," + time);
}
}
else if ("init".equals(type)) {
// Match initialization timing: initialization completed in X ms
Pattern pattern = Pattern.compile("initialization completed in (\\d+) ms");
Matcher matcher = pattern.matcher(line);
if (matcher.find()) {
String time = matcher.group(1);
writer.println(time);
}
}
else if ("token".equals(type)) {
// Match token timing: 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 time = matcher.groupCount() > 1 && matcher.group(2) != null ? matcher.group(2) : "N/A";
writer.println(tokenId + "," + time);
}
}
}
}
}
private static void comparePerformance(File beforeFile, File afterFile, File outputFile, String type) throws IOException {
// Check if input files exist
if (!beforeFile.exists() || !afterFile.exists()) {
System.out.println("Warning: One or both input files missing for " + type + " comparison");
return;
}
if ("controller".equals(type)) {
compareControllerPerformance(beforeFile, afterFile, outputFile);
} else if ("init".equals(type)) {
compareInitPerformance(beforeFile, afterFile, outputFile);
} else if ("token".equals(type)) {
compareTokenPerformance(beforeFile, afterFile, outputFile);
}
}
private static void compareControllerPerformance(File beforeFile, File afterFile, File outputFile) throws IOException {
// Load before data
Map> beforeMethods = new HashMap<>();
try (BufferedReader reader = new BufferedReader(new FileReader(beforeFile))) {
// Skip header
reader.readLine();
String line;
while ((line = reader.readLine()) != null) {
String[] parts = line.split(",");
if (parts.length >= 3) {
String key = parts[0] + "," + parts[1]; // Controller,Method
double time = Double.parseDouble(parts[2]);
beforeMethods.computeIfAbsent(key, k -> new ArrayList<>()).add(time);
}
}
}
// Load after data
Map> afterMethods = new HashMap<>();
try (BufferedReader reader = new BufferedReader(new FileReader(afterFile))) {
// Skip header
reader.readLine();
String line;
while ((line = reader.readLine()) != null) {
String[] parts = line.split(",");
if (parts.length >= 3) {
String key = parts[0] + "," + parts[1]; // Controller,Method
double time = Double.parseDouble(parts[2]);
afterMethods.computeIfAbsent(key, k -> new ArrayList<>()).add(time);
}
}
}
// Generate comparison report
try (PrintWriter writer = new PrintWriter(new FileWriter(outputFile))) {
writer.println("Controller,Method,CountBefore,CountAfter,AvgBefore,AvgAfter,Improvement%");
// Get all unique keys
Set allKeys = new HashSet<>();
allKeys.addAll(beforeMethods.keySet());
allKeys.addAll(afterMethods.keySet());
// Sort keys
List sortedKeys = new ArrayList<>(allKeys);
Collections.sort(sortedKeys);
for (String key : sortedKeys) {
String[] parts = key.split(",");
String controller = parts[0];
String method = parts[1];
List beforeTimes = beforeMethods.getOrDefault(key, Collections.emptyList());
List afterTimes = afterMethods.getOrDefault(key, Collections.emptyList());
// Only include if we have data in both periods
if (!beforeTimes.isEmpty() && !afterTimes.isEmpty()) {
double beforeAvg = beforeTimes.stream().mapToDouble(Double::doubleValue).average().orElse(0);
double afterAvg = afterTimes.stream().mapToDouble(Double::doubleValue).average().orElse(0);
double improvement = beforeAvg > 0 ? ((beforeAvg - afterAvg) / beforeAvg) * 100 : 0;
writer.printf("%s,%s,%d,%d,%.2f,%.2f,%.2f%n",
controller, method,
beforeTimes.size(), afterTimes.size(),
beforeAvg, afterAvg, improvement);
}
}
}
}
private static void compareInitPerformance(File beforeFile, File afterFile, File outputFile) throws IOException {
// Load before data
List beforeTimes = new ArrayList<>();
try (BufferedReader reader = new BufferedReader(new FileReader(beforeFile))) {
// Skip header
reader.readLine();
String line;
while ((line = reader.readLine()) != null) {
try {
double time = Double.parseDouble(line.trim());
beforeTimes.add(time);
} catch (NumberFormatException e) {
// Skip invalid lines
}
}
}
// Load after data
List afterTimes = new ArrayList<>();
try (BufferedReader reader = new BufferedReader(new FileReader(afterFile))) {
// Skip header
reader.readLine();
String line;
while ((line = reader.readLine()) != null) {
try {
double time = Double.parseDouble(line.trim());
afterTimes.add(time);
} catch (NumberFormatException e) {
// Skip invalid lines
}
}
}
// Generate comparison report
try (PrintWriter writer = new PrintWriter(new FileWriter(outputFile))) {
writer.println("Metric,Before,After,Improvement%");
double beforeAvg = beforeTimes.stream().mapToDouble(Double::doubleValue).average().orElse(0);
double afterAvg = afterTimes.stream().mapToDouble(Double::doubleValue).average().orElse(0);
double improvement = beforeAvg > 0 ? ((beforeAvg - afterAvg) / beforeAvg) * 100 : 0;
writer.printf("Average Initialization,%.2f,%.2f,%.2f%n", beforeAvg, afterAvg, improvement);
// Additional statistics
if (!beforeTimes.isEmpty() && !afterTimes.isEmpty()) {
Collections.sort(beforeTimes);
Collections.sort(afterTimes);
writer.printf("Minimum Initialization,%.2f,%.2f,N/A%n",
beforeTimes.get(0), afterTimes.get(0));
writer.printf("Maximum Initialization,%.2f,%.2f,N/A%n",
beforeTimes.get(beforeTimes.size() - 1), afterTimes.get(afterTimes.size() - 1));
}
}
}
private static void compareTokenPerformance(File beforeFile, File afterFile, File outputFile) throws IOException {
// For token performance, we'll just calculate average execution time across all tokens
// Load before data
List beforeTimes = new ArrayList<>();
try (BufferedReader reader = new BufferedReader(new FileReader(beforeFile))) {
// Skip header
reader.readLine();
String line;
while ((line = reader.readLine()) != null) {
String[] parts = line.split(",");
if (parts.length >= 2 && !"N/A".equals(parts[1])) {
try {
double time = Double.parseDouble(parts[1].trim());
beforeTimes.add(time);
} catch (NumberFormatException e) {
// Skip invalid lines
}
}
}
}
// Load after data
List afterTimes = new ArrayList<>();
try (BufferedReader reader = new BufferedReader(new FileReader(afterFile))) {
// Skip header
reader.readLine();
String line;
while ((line = reader.readLine()) != null) {
String[] parts = line.split(",");
if (parts.length >= 2 && !"N/A".equals(parts[1])) {
try {
double time = Double.parseDouble(parts[1].trim());
afterTimes.add(time);
} catch (NumberFormatException e) {
// Skip invalid lines
}
}
}
}
// Generate comparison report
try (PrintWriter writer = new PrintWriter(new FileWriter(outputFile))) {
writer.println("Metric,Before,After,Improvement%");
double beforeAvg = beforeTimes.stream().mapToDouble(Double::doubleValue).average().orElse(0);
double afterAvg = afterTimes.stream().mapToDouble(Double::doubleValue).average().orElse(0);
double improvement = beforeAvg > 0 ? ((beforeAvg - afterAvg) / beforeAvg) * 100 : 0;
writer.printf("Average Token Time,%.2f,%.2f,%.2f%n", beforeAvg, afterAvg, improvement);
writer.printf("Token Count,%d,%d,N/A%n", beforeTimes.size(), afterTimes.size());
}
}
}