我想出了以下Groovy脚本。当然,它已经非常适应我的需求,但是我希望它能对某人有所帮助。
def traceMap = [:]// Number of lines to keep in bufferdef BUFFER_SIZE = 100// Pattern for stack trace linedef TRACE_LINE_PATTERN = '^[\s\t]+at .*$'// Log line pattern between which we try to capture full tracedef LOG_LINE_PATTERN = '^([<#][^/]|\d\d).*$'// List of patterns to replace in final captured stack trace line // (e.g. replace date and transaction information that may make similar traces to look as different)def REPLACE_PATTERNS = [ '^\d+-\d+\@.*?tksId: [^\]]+\]', '^<\w+ \d+, \d+ [^>]*?> <[^>]*?> <[^>]*?> <[^>]*?> <', '^####<[^>]+?> <[^>]*?> <[^>]*?> <[^>]*?> <[^>]*?> <[^>]*?> <[^>]*?> <[^>]*?> <[^>]*?> <[^>]*?> <[^>]*?> <', '<([\w:]+)?TransaktionsID>[^<]+?</([\w:]+)?TransaktionsID>', '<([\w:]+)?TransaktionsTid>[^<]+?</([\w:]+)?TransaktionsTid>']new File('.').eachFile { File file -> if (file.name.contains('.log') || file.name.contains('.out')) { def bufferLines = [] file.withReader { Reader reader -> while (reader.ready()) { def String line = reader.readLine() if (line.matches(TRACE_LINE_PATTERN)) { def trace = [] for(def i = bufferLines.size() - 1; i >= 0; i--) { if (!bufferLines[i].matches(LOG_LINE_PATTERN)) { trace.add(0, bufferLines[i]) } else { trace.add(0, bufferLines[i]) break } } trace.add(line) if (reader.ready()) { line = reader.readLine() while (!line.matches(LOG_LINE_PATTERN)) { trace.add(line) if (reader.ready()) { line = reader.readLine() } else { break; } } } def traceString = trace.join("n") REPLACE_PATTERNS.each { pattern -> traceString = traceString.replaceAll(pattern, '') } if (traceMap.containsKey(traceString)) { traceMap.put(traceString, traceMap.get(traceString) + 1) } else { traceMap.put(traceString, 1) } } // Keep the buffer of last lines. bufferLines.add(line) if (bufferLines.size() > BUFFER_SIZE) { bufferLines.remove(0) } } } }}traceMap = traceMap.sort { it.value }traceMap.reverseEach { trace, number -> println "-- Occured $number times -----------------------------------------" println trace}


