Wb

Charlie Fubon - Feb 28 - - Dev Community

import java.io.*;
import java.nio.file.*;
import java.text.DecimalFormat;
import java.util.*;
import java.util.regex.*;
import java.util.stream.Collectors;

/**
 * WebLogic Performance Analyzer
 * Analyzes WebLogic server logs to compare performance before and after infrastructure upgrades.
 */
public class WebLogicPerformanceAnalyzer {

    // Regular expressions for different timing patterns
    private static final Pattern INIT_PATTERN = Pattern.compile("initialization completed in (\\d+) ms");
    private static final Pattern TIME_TAKEN_PATTERN = Pattern.compile("\\*\\|\\*Time taken for\\*\\|\\*(.+?)\\*\\|\\*is\\*\\|\\*(\\d+)\\*\\|\\*ms");
    private static final Pattern THREAD_INFO_PATTERN = Pattern.compile("ExecuteThread: '(\\d+)'");

    // Filter out non-performance related patterns containing "ms"
    private static final Pattern TOKEN_EXPIRY_PATTERN = Pattern.compile("token to expire");
    private static final Pattern SYSTEM_DATETIME_PATTERN = Pattern.compile("system date time");

    public static void main(String[] args) {
        if (args.length < 2) {
            System.out.println("Usage: java WebLogicPerformanceAnalyzer <beforeLogsDir> <afterLogsDir>");
            System.out.println("Example: java WebLogicPerformanceAnalyzer ./logs/before ./logs/after");
            return;
        }

        String beforeDir = args[0];
        String afterDir = args[1];

        try {
            // Process "before" and "after" logs
            Map<String, List<Integer>> beforeOperationTimes = processLogsDirectory(beforeDir);
            Map<String, List<Integer>> afterOperationTimes = processLogsDirectory(afterDir);

            // Generate performance comparison report
            generateReport(beforeOperationTimes, afterOperationTimes);

        } catch (IOException e) {
            System.err.println("Error processing log files: " + e.getMessage());
            e.printStackTrace();
        }
    }

    /**
     * Process all log files in a directory
     */
    private static Map<String, List<Integer>> processLogsDirectory(String directoryPath) throws IOException {
        Map<String, List<Integer>> operationTimes = new HashMap<>();

        File directory = new File(directoryPath);
        File[] logFiles = directory.listFiles((dir, name) -> name.toLowerCase().endsWith(".txt") || name.toLowerCase().endsWith(".log"));

        if (logFiles != null) {
            for (File logFile : logFiles) {
                processLogFile(logFile, operationTimes);
            }
        }

        return operationTimes;
    }

    /**
     * Process a single log file to extract timing information
     */
    private static void processLogFile(File logFile, Map<String, List<Integer>> operationTimes) throws IOException {
        try (BufferedReader reader = new BufferedReader(new FileReader(logFile))) {
            String line;
            while ((line = reader.readLine()) != null) {
                // Skip lines with token expiry or system datetime
                if (TOKEN_EXPIRY_PATTERN.matcher(line).find() || SYSTEM_DATETIME_PATTERN.matcher(line).find()) {
                    continue;
                }

                // Extract initialization times
                Matcher initMatcher = INIT_PATTERN.matcher(line);
                if (initMatcher.find()) {
                    int timeMs = Integer.parseInt(initMatcher.group(1));
                    addOperationTime(operationTimes, "initialization", timeMs);
                    continue;
                }

                // Extract "Time taken for" operation times
                Matcher timeTakenMatcher = TIME_TAKEN_PATTERN.matcher(line);
                if (timeTakenMatcher.find()) {
                    String operation = timeTakenMatcher.group(1);
                    int timeMs = Integer.parseInt(timeTakenMatcher.group(2));
                    addOperationTime(operationTimes, operation, timeMs);
                }
            }
        }
    }

    /**
     * Add operation time to the map
     */
    private static void addOperationTime(Map<String, List<Integer>> operationTimes, String operation, int timeMs) {
        operationTimes.computeIfAbsent(operation, k -> new ArrayList<>()).add(timeMs);
    }

    /**
     * Generate a performance comparison report
     */
    private static void generateReport(Map<String, List<Integer>> beforeTimes, Map<String, List<Integer>> afterTimes) {
        System.out.println("WebLogic Performance Analysis Report");
        System.out.println("=====================================");
        System.out.println();

        // Create a unified set of all operations from both before and after
        Set<String> allOperations = new HashSet<>();
        allOperations.addAll(beforeTimes.keySet());
        allOperations.addAll(afterTimes.keySet());

        // Sort operations by average time in "before" logs (descending)
        List<String> sortedOperations = allOperations.stream()
                .sorted((op1, op2) -> {
                    double avg1 = beforeTimes.containsKey(op1) ? calculateAverage(beforeTimes.get(op1)) : 0;
                    double avg2 = beforeTimes.containsKey(op2) ? calculateAverage(beforeTimes.get(op2)) : 0;
                    return Double.compare(avg2, avg1); // Descending order
                })
                .collect(Collectors.toList());

        // Print table header
        System.out.printf("%-40s | %-15s | %-15s | %-15s%n", "Operation", "Before Upgrade", "After Upgrade", "Improvement");
        System.out.println(String.join("", Collections.nCopies(95, "-")));

        DecimalFormat df = new DecimalFormat("#,##0.00");

        // Print each operation's statistics
        for (String operation : sortedOperations) {
            double beforeAvg = beforeTimes.containsKey(operation) ? calculateAverage(beforeTimes.get(operation)) : 0;
            double afterAvg = afterTimes.containsKey(operation) ? calculateAverage(afterTimes.get(operation)) : 0;

            String beforeStr = beforeTimes.containsKey(operation) ? df.format(beforeAvg) + " ms" : "N/A";
            String afterStr = afterTimes.containsKey(operation) ? df.format(afterAvg) + " ms" : "N/A";

            String improvementStr = "N/A";
            if (beforeTimes.containsKey(operation) && afterTimes.containsKey(operation) && beforeAvg > 0) {
                double improvementPct = ((beforeAvg - afterAvg) / beforeAvg) * 100;
                improvementStr = df.format(improvementPct) + "%";
            }

            System.out.printf("%-40s | %-15s | %-15s | %-15s%n", 
                    operation.length() > 40 ? operation.substring(0, 37) + "..." : operation,
                    beforeStr, afterStr, improvementStr);
        }

        System.out.println();
        System.out.println("Summary Statistics");
        System.out.println("-----------------");

        // Calculate overall average improvement
        List<Double> improvementPercentages = new ArrayList<>();
        for (String operation : allOperations) {
            if (beforeTimes.containsKey(operation) && afterTimes.containsKey(operation)) {
                double beforeAvg = calculateAverage(beforeTimes.get(operation));
                double afterAvg = calculateAverage(afterTimes.get(operation));
                if (beforeAvg > 0) {
                    double improvementPct = ((beforeAvg - afterAvg) / beforeAvg) * 100;
                    improvementPercentages.add(improvementPct);
                }
            }
        }

        if (!improvementPercentages.isEmpty()) {
            double avgImprovement = calculateAverage(improvementPercentages);
            System.out.println("Average performance improvement across all operations: " + df.format(avgImprovement) + "%");
        }

        // Top 5 most improved operations
        if (!improvementPercentages.isEmpty()) {
            System.out.println();
            System.out.println("Top 5 Most Improved Operations");
            System.out.println("-----------------------------");

            allOperations.stream()
                .filter(op -> beforeTimes.containsKey(op) && afterTimes.containsKey(op))
                .sorted((op1, op2) -> {
                    double beforeAvg1 = calculateAverage(beforeTimes.get(op1));
                    double afterAvg1 = calculateAverage(afterTimes.get(op1));
                    double imp1 = beforeAvg1 > 0 ? ((beforeAvg1 - afterAvg1) / beforeAvg1) * 100 : 0;

                    double beforeAvg2 = calculateAverage(beforeTimes.get(op2));
                    double afterAvg2 = calculateAverage(afterTimes.get(op2));
                    double imp2 = beforeAvg2 > 0 ? ((beforeAvg2 - afterAvg2) / beforeAvg2) * 100 : 0;

                    return Double.compare(imp2, imp1); // Descending order
                })
                .limit(5)
                .forEach(op -> {
                    double beforeAvg = calculateAverage(beforeTimes.get(op));
                    double afterAvg = calculateAverage(afterTimes.get(op));
                    double improvementPct = ((beforeAvg - afterAvg) / beforeAvg) * 100;
                    System.out.printf("%-40s: %s%% improvement (%s ms → %s ms)%n",
                            op.length() > 40 ? op.substring(0, 37) + "..." : op,
                            df.format(improvementPct),
                            df.format(beforeAvg),
                            df.format(afterAvg));
                });
        }
    }

    /**
     * Calculate average of a list of integers
     */
    private static double calculateAverage(List<Integer> values) {
        if (values == null || values.isEmpty()) {
            return 0;
        }
        return values.stream().mapToDouble(Integer::doubleValue).average().orElse(0);
    }

    /**
     * Calculate average of a list of doubles
     */
    private static double calculateAverage(List<Double> values) {
        if (values == null || values.isEmpty()) {
            return 0;
        }
        return values.stream().mapToDouble(Double::doubleValue).average().orElse(0);
    }
}

Enter fullscreen mode Exit fullscreen mode
. . . . .