import java.io.IOException;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class SQLAnalyzerJava8 {
private static class QueryStats {
String query;
int stuckCount;
int activeCount;
Set<String> threadIds = new HashSet<>();
Set<Integer> lineNumbers = new HashSet<>();
public QueryStats(String query) {
this.query = query;
}
}
private static final Pattern LOG_PATTERN = Pattern.compile(
"Line (\d+): DEBUG .*?" +
"\[(STUCK|ACTIVE)\] " +
"ExecuteThread: '(\d+)' .*?" +
"(?:Preparing: )?(SELECT.+?)(?:;\s*$|(?=Line \d+: DEBUG))",
Pattern.DOTALL
);
// ** We're not using file reading for now **
// private static final String LOG_FILE_PATH = "C:/Users/Downloads/client_load.log";
public void analyzeLogs() {
Map<String, QueryStats> statsMap = new HashMap<>();
// Hardcoded test lines (replace with your actual log line format if needed)
String[] testLines = {
"Line 1: DEBUG [STUCK] ExecuteThread: '123' Preparing: SELECT * FROM users WHERE id = 1;",
"Line 2: DEBUG [ACTIVE] ExecuteThread: '456' Preparing: SELECT * FROM products WHERE category = 'Electronics';",
"Line 3: DEBUG [STUCK] ExecuteThread: '123' Preparing: SELECT * FROM users WHERE id = 1;", // Duplicate query
"Line 4: DEBUG [ACTIVE] ExecuteThread: '789' SELECT * FROM orders WHERE order_date BETWEEN '2023-01-01' AND '2023-12-31';"
};
// Simulate reading the lines
for (String line : testLines) {
processLine(statsMap, line);
}
printAnalysis(statsMap);
}
private void processLine(Map<String, QueryStats> statsMap, String line) {
Matcher matcher = LOG_PATTERN.matcher(line);
if (matcher.find()) {
Integer currentLineNum = Integer.parseInt(matcher.group(1));
String currentStatus = matcher.group(2);
String currentThread = matcher.group(3);
String queryPart = matcher.group(4);
// If queryPart is null, we might be at the end of a multi-line query
// In this simplified example, we assume single-line queries
if (queryPart != null) {
finalizeQuery(statsMap, queryPart, currentStatus, currentThread, currentLineNum);
}
} else {
System.out.println("No match found for line: " + line);
}
}
private void finalizeQuery(Map<String, QueryStats> statsMap, String query, String status, String threadId, Integer lineNum) {
String normalizedQuery = normalizeQuery(query);
QueryStats stats = statsMap.get(normalizedQuery);
if (stats == null) {
stats = new QueryStats(normalizedQuery);
statsMap.put(normalizedQuery, stats);
}
if ("STUCK".equals(status)) {
stats.stuckCount++;
} else if ("ACTIVE".equals(status)) {
stats.activeCount++;
}
stats.threadIds.add(threadId);
stats.lineNumbers.add(lineNum);
}
private String normalizeQuery(String query) {
// ... (Your normalization logic - this should be fine)
if (query == null) {
return "";
}
query = query.replaceAll("\s+", " ").trim();
// Normalize parameter placeholders
query = query.replaceAll("=\s*\?", "= ?");
query = query.replaceAll("IN\s*\([^)]*\)", "IN (?)");
// Normalize numbers in identifiers
query = query.replaceAll("\b\d+\b", "?");
// Normalize quoted strings
query = query.replaceAll("'[^']*'", "?");
// Handle BETWEEN
query = query.replaceAll("BETWEEN\s*\?\s*AND\s*\?", "BETWEEN ? AND ?");
// Handle LIKE
query = query.replaceAll("LIKE\s*\?", "LIKE ?");
return query;
}
private void printAnalysis(Map<String, QueryStats> statsMap) {
System.out.println("=== SQL Query Analysis ===n");
List<QueryStats> sortedStats = new ArrayList<>(statsMap.values());
Collections.sort(sortedStats, new Comparator<QueryStats>() {
@Override
public int compare(QueryStats s1, QueryStats s2) {
return Integer.compare(s2.stuckCount + s2.activeCount, s1.stuckCount + s1.activeCount);
}
});
for (QueryStats stats : sortedStats) {
System.out.println("Query: " + stats.query);
System.out.println("Stuck Count: " + stats.stuckCount);
System.out.println("Active Count: " + stats.activeCount);
System.out.println("Thread IDs: " + stats.threadIds);
System.out.println("Line Numbers: " + stats.lineNumbers);
System.out.println("--------------------------------------------------------------------------------n");
}
}
public static void main(String[] args) {
SQLAnalyzerJava8 analyzer = new SQLAnalyzerJava8();
analyzer.analyzeLogs();
}
}
Source link
lol