在 Log4J 中捕获异常后如何在单独的行中打印堆栈跟踪

How to print stack traces in separated lines after catching exception in Log4J

目前,我可以获得堆栈跟踪:

final StringWriter sw = new StringWriter();
final PrintWriter pw = new PrintWriter(sw, true);
throwable.printStackTrace(pw);
String stackTraceAsString = sw.getBuffer().toString();

但是当调用 errors()、debug() 等日志函数时,我只能在 1 行中获取所有堆栈跟踪,尽管堆栈跟踪字符串包含 \r\n。我想把它分成几行。

查看 Appender class:

@Override
protected void subAppend(LoggingEvent event) {
    this.qw.write(this.layout.format(event));

    if (this.layout.ignoresThrowable()) {
        String[] s = event.getThrowableStrRep();
        if (s != null) {
            int len = s.length;
            for (int i = 0; i < len; i++) {
                this.qw.write(s[i]);
                this.qw.write(Layout.LINE_SEP);
            }
        }
    }
    if (this.immediateFlush) {
        this.qw.flush();
    }
}

但是,它只处理抛出而未被捕获的异常。因此,我正在实施一个自定义的附加程序:

public class CustomRollingFileAppender extends RollingFileAppender {
}

我试图从 class 中的 QuiteWriter 变量中提取字符串,用 Layout.LINE_SEP 替换“\r\n”,但我不知道如何提取它。

总之不行,没有办法覆盖常量接口变量(Layout.LINE_SEP是定义在中的常量变量)

此外,您没有覆盖 Java 中的 class 变量,您隐藏了它们。覆盖是例如方法。隐藏不同于覆盖。

因为 Layout.LINE_SEP 没有可用的 getter 或 setter 方法,我们也不能覆盖。

关于您的问题,您不需要将堆栈跟踪打印到 String 然后记录它。 LOG4J 提供了为您打印堆栈跟踪的方法。

例如。

public void log(Priority priority, Object message, Throwable t)

public void error(Object message, Throwable t)

exception 对象传递给 throwable 类型的变量 t 将打印堆栈跟踪以及换行符。