基于Log4j日志过滤指定类抛出的ERROR级异常栈信息
提取Log4j日志中ExampleClass相关的ERROR异常栈跟踪
我经常处理这类日志提取需求,这里分享两种实用的方法,帮你精准捕获目标异常信息:
方法一:用Linux命令行快速提取(适合日志文件直接分析)
如果是在Linux环境下,用grep+awk组合可以快速搞定,不需要写代码。这个命令会精准匹配包含ExampleClass的ERROR行,然后捕获后续的Exception行和完整栈跟踪(包括Caused by行):
grep -A 100 -B 0 "ERROR.*ExampleClass" your-log-file.log | awk ' /ERROR/ {print; getline; print; in_stack=1} in_stack { print; # 当遇到非栈跟踪行时停止捕获 if ($0 !~ /^\s+at / && $0 !~ /^Caused by:/) in_stack=0 } '
命令解释:
grep -A 100 "ERROR.*ExampleClass":匹配所有包含ExampleClass的ERROR行,并取该行之后的100行(数字可以根据你的栈跟踪长度调整,确保覆盖完整栈)awk部分:- 先打印匹配到的ERROR行,然后读取并打印下一行(通常是包含Exception的行)
- 开启栈跟踪捕获模式,持续打印直到遇到非栈跟踪行(既不是以空格+
at开头,也不是Caused by:开头的行)
方法二:用Java代码解析(适合集成到程序中)
如果需要在Java应用里处理日志文件,可以写一个简单的解析工具,逻辑清晰且可定制:
import java.io.BufferedReader; import java.io.FileReader; import java.io.IOException; import java.util.ArrayList; import java.util.List; public class LogExceptionExtractor { public static void main(String[] args) { String logFilePath = "path/to/your/logfile.log"; boolean isCapturingStack = false; List<String> currentExceptionLines = new ArrayList<>(); try (BufferedReader reader = new BufferedReader(new FileReader(logFilePath))) { String line; while ((line = reader.readLine()) != null) { // 触发捕获:找到目标ERROR行 if (line.startsWith("ERROR") && line.contains("ExampleClass")) { isCapturingStack = true; currentExceptionLines.add(line); // 读取并添加紧接着的Exception行 if ((line = reader.readLine()) != null) { currentExceptionLines.add(line); } } else if (isCapturingStack) { // 判断是否属于栈跟踪内容 boolean isStackLine = line.trim().startsWith("at ") || line.startsWith("Caused by:"); if (isStackLine) { currentExceptionLines.add(line); } else { // 栈跟踪结束,输出结果并重置 printExtractedException(currentExceptionLines); currentExceptionLines.clear(); isCapturingStack = false; } } } // 处理日志末尾未输出的最后一个异常 if (!currentExceptionLines.isEmpty()) { printExtractedException(currentExceptionLines); } } catch (IOException e) { System.err.println("读取日志文件失败:" + e.getMessage()); e.printStackTrace(); } } private static void printExtractedException(List<String> exceptionLines) { System.out.println("\n===== 提取到的异常信息 ====="); exceptionLines.forEach(System.out::println); System.out.println("===========================\n"); } }
代码逻辑说明:
- 逐行读取日志文件,当匹配到包含
ExampleClass的ERROR行时,开启捕获模式 - 先记录ERROR行,再读取并记录下一行(通常是
XXXException: 异常信息的行) - 后续持续记录栈跟踪行,直到遇到非栈跟踪内容(比如下一条日志的INFO/WARNING开头行)
- 每次捕获完成后,格式化输出提取到的异常信息
小提示:
- 如果你的日志格式有特殊情况(比如栈行的缩进不同),可以调整
isStackLine的判断条件,比如用正则表达式更精准匹配 - 命令行中的
-A 100如果不够用,可以改成更大的数字,比如-A 200,确保覆盖最长的栈跟踪
内容的提问来源于stack exchange,提问作者Bartosz
相关产品推荐
相关产品推荐

