【问题标题】:Log4j formatting: Is it possible to truncate stacktraces?Log4j 格式:是否可以截断堆栈跟踪?
【发布时间】:2011-03-16 21:04:47
【问题描述】:

我只想在我的程序中记录前几行异常。我知道,我可以这样做来只打印堆栈跟踪的前 5 行:

Throwable e = ...;
StackTraceElement[] stack = e.getStackTrace();
int maxLines = (stack.length > 4) ? 5 : stack.length;
for (int n = 0; n < maxLines; n++) {
    System.err.println(stack[n].toString());
}

但我宁愿使用 log4j(或者更准确地说是 slf4j 而不是 log4j)进行日志记录。有没有办法告诉 log4j 它应该只打印堆栈跟踪的前 5 行?

【问题讨论】:

    标签: java logging log4j stack-trace


    【解决方案1】:

    您可以在 log4j 中使用 EnhancedPatternLayout 来格式化您的堆栈跟踪。

    参见http://logging.apache.org/log4j/1.2/apidocs/org/apache/log4j/EnhancedPatternLayout.html,特别是模式表中关于“可投掷”模式的部分。

    请注意,对 %throwable{n} 的支持是相当新的,至少需要 log4j 1.2.16(这是撰写本文时的最新版本)

    出于跟踪目的,这是处理其实施的票证: https://issues.apache.org/bugzilla/show_bug.cgi?id=48902

    【讨论】:

    • 请注意,在嵌套异常的情况下,这将无情地切断嵌套消息,因此对于许多实际用例来说,这是无用的。开发人员需要限制跟踪中每个异常的堆栈元素数量。
    • 如果使用slf4j-log4j12log4j-slf4j-impl,这个%throwable{...} 模式是否也可用于slf4j?
    • 是的,它可以工作,需要添加 log4j-over-slf4j 桥依赖。 @GeroldBroser
    【解决方案2】:

    是的……EnhancedPatternLayout 提供了这个功能。 (从 Log4J-1.2.16 开始,之前在额外的同伴中)。

    对于一个 log4j 配置

    <appender name="Console" class="org.apache.log4j.ConsoleAppender">
        <param name="Threshold" value="debug"/>
        <layout class="org.apache.log4j.EnhancedPatternLayout">
            <param name="ConversionPattern" value="%d %-5p [%t] %c.%M - %m%n %throwable{short}"/>
        </layout>
    </appender>
    

    对于一段像

    这样的 Java 代码

    抛出新异常(新 Exception("内部异常"));

    您在日志文件中得到以下内容...

    java.lang.Exception: java.lang.Exception: 内部异常

    如果我们从 log4j 配置文件中删除“%throwable{short}”,我们将获得完整的堆栈跟踪

    【讨论】:

    • 异常中是否可以隐藏消息“Inner Exception”?
    【解决方案3】:

    在 log4j2.xml 中,只需在末尾添加 %throwable{short}。无需添加参数名称。

    <PatternLayout pattern="%d{yyy-MM-dd HH:mm:ss.SSS} [%t] %-5level %logger{36} - %m%n %throwable{short} %n"/>
    

    参考:https://logging.apache.org/log4j/2.x/manual/layouts.html#PatternLayout

    【讨论】:

      【解决方案4】:

      我不知道有这样的选择。但是你可以扩展你当前的 appender(例如 RollingFileAppender)并提供一个 append / doAppend / subAppend 方法(取决于你要扩展的类)来处理这个问题。

      可投掷信息包含在LoggingEvent.throwableInformation

      也就是说,我不确定您是否应该这样做 - 这样您可能会丢失重要信息。

      【讨论】:

        【解决方案5】:

        是的,它是自 log4j 1.2.16 以来 log4j 的一部分

        这是 Apache 问题跟踪器中的原始提案,详细描述了 %throwable 模式的每个应用程序的外观: https://issues.apache.org/bugzilla/show_bug.cgi?id=48902#c0

        【讨论】:

          猜你喜欢
          • 2012-01-29
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2011-05-19
          • 2011-01-18
          • 1970-01-01
          • 2018-04-17
          相关资源
          最近更新 更多