You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于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");
    }
}

代码逻辑说明:

  1. 逐行读取日志文件,当匹配到包含ExampleClass的ERROR行时,开启捕获模式
  2. 先记录ERROR行,再读取并记录下一行(通常是XXXException: 异常信息的行)
  3. 后续持续记录栈跟踪行,直到遇到非栈跟踪内容(比如下一条日志的INFO/WARNING开头行)
  4. 每次捕获完成后,格式化输出提取到的异常信息

小提示:

  • 如果你的日志格式有特殊情况(比如栈行的缩进不同),可以调整isStackLine的判断条件,比如用正则表达式更精准匹配
  • 命令行中的-A 100如果不够用,可以改成更大的数字,比如-A 200,确保覆盖最长的栈跟踪

内容的提问来源于stack exchange,提问作者Bartosz

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.19 07:47:49