DEV Community

Charlie Fubon
Charlie Fubon

Posted on

F2


// Only showing the modified parts that need to change:

public class SQLAnalyzer {
    // Updated pattern to properly capture all states
    private static final Pattern LOG_PATTERN = Pattern.compile(
        // First part captures ACTIVE/STUCK states
        "\\[(ACTIVE|STUCK)\\].*?ExecuteThread: '(\\d+)'.*?(?:preparing:|select)\\s+(.+?)(?=\\[|$)|" +
        // Second part captures Async-Pool threads
        "\\[(Async-Pool-\\d+-Thread-\\d+)\\].*?(?:preparing:|select)\\s+(.+?)(?=\\[|$)",
        Pattern.CASE_INSENSITIVE);

    private void processLine(String line, int lineNumber) {
        Matcher matcher = LOG_PATTERN.matcher(line);
        if (matcher.find()) {
            String state;
            String threadId;
            String sqlStatement;
            boolean isAsyncPool;

            // Check if this is a regular (ACTIVE/STUCK) thread
            if (matcher.group(1) != null) {
                // Regular thread case
                state = matcher.group(1);
                threadId = matcher.group(2);
                sqlStatement = matcher.group(3);
                isAsyncPool = false;
            } else {
                // Async-Pool thread case
                state = matcher.group(4);
                threadId = state;  // Use the full Async-Pool-X-Thread-Y as the ID
                sqlStatement = matcher.group(5);
                isAsyncPool = true;
            }

            if (sqlStatement != null) {
                // Normalize SQL statement
                String normalizedSQL = sqlStatement.replaceAll("\\s+", " ").trim();

                // Add to distribution
                queryDistribution
                    .computeIfAbsent(normalizedSQL, QueryStats::new)
                    .addOccurrence(threadId, state, lineNumber, isAsyncPool);

                knownStates.add(state);
            }
        }
    }

    // Optional debug method to help verify pattern matching
    private void debugProcessLine(String line) {
        System.out.println("\nAnalyzing line: " + line);
        Matcher matcher = LOG_PATTERN.matcher(line);
        if (matcher.find()) {
            System.out.println("Match found!");
            System.out.println("Regular thread state: " + matcher.group(1));
            System.out.println("Regular thread ID: " + matcher.group(2));
            System.out.println("Regular thread SQL: " + matcher.group(3));
            System.out.println("Async thread full state: " + matcher.group(4));
            System.out.println("Async thread SQL: " + matcher.group(5));
        } else {
            System.out.println("No match found");
        }
    }

    // Add this to main method for debugging
    public static void main(String[] args) {
        if (args.length < 2) {
            System.out.println("Usage: java SQLAnalyzer <log-file-path> <output-file-path> [--debug]");
            return;
        }

        SQLAnalyzer analyzer = new SQLAnalyzer();
        try {
            boolean debug = args.length > 2 && args[2].equals("--debug");

            if (debug) {
                // Read first few lines for debugging
                try (BufferedReader reader = new BufferedReader(new FileReader(args[0]))) {
                    String line;
                    int count = 0;
                    while ((line = reader.readLine()) != null && count < 5) {
                        analyzer.debugProcessLine(line);
                        count++;
                    }
                }
                return;
            }

            analyzer.analyzeLogs(args[0]);
            analyzer.writeAnalysisToFile(args[1]);
            System.out.println("\nAnalysis complete. Results have been written to: " + args[1]);
        } catch (IOException e) {
            System.err.println("Error: " + e.getMessage());
            e.printStackTrace();
        }
    }
}

Enter fullscreen mode Exit fullscreen mode

Top comments (0)