繁体   English   中英

如何让 log4j syslog appender 在一行中写入堆栈跟踪?

[英]How to make log4j syslog appender write a stack trace in one line?

我正在使用 log4j syslog appender 并注意到当发生异常时,appender 将堆栈跟踪中的每个条目都写为一个新行。

有没有办法配置它,以便整个堆栈跟踪将作为一行而不是多行?

我正在使用以下 log4j2 配置,它可以很好地发送到 syslog,并且不需要更改代码即可将所有这些异常转换为字符串。 它只是用异常的管道替换默认的 lineep 。

    <Syslog name="SYSLOG" host="127.0.0.1" port="515" protocol="TCP" charset="UTF-8"
            immediateFail="false" ignoreExceptions="true" reconnectionDelayMillis="250">
        <PatternLayout pattern="[%d] %-5p %m%n %throwable{separator(|)}"></PatternLayout>
    </Syslog>

日志4j2

詹姆斯的回答

Log4j v1

默认情况下,syslog appender 将格式化日志以及堆栈跟踪的每一行作为单独的日志条目发送到 syslog。 因为 syslog 使用 UDP,所以这些行可能会乱序。

如果这是您要解决的问题,那么正如詹姆斯所说,最好的方法是使用带有%throwable转换字符的模式布局。 他记录了如何为 log4j2 做到这一点。 对于 log4j1,它需要EnhancedPatternLayout

<appender name="syslog" class="org.apache.log4j.net.SyslogAppender">
  <param name="SyslogHost" value="127.0.0.1:514"/>
  <layout class="org.apache.log4j.EnhancedPatternLayout">
    <param name="ConversionPattern" value="[%d] %-5p %m%n%throwable"/>
  </layout>
</appender>

请注意,上述解决方案仍将使用换行符来分隔堆栈跟踪的各个行,但它将解决堆栈跟踪行在 syslog 中作为单独的日志条目发送的问题。

如果你真的想要一行上的堆栈跟踪,一个快速的解决方法是使用上面的例子和%throwable{short}%throwable{1} ,这将只包括堆栈跟踪的第一行。

如果您希望在一行中显示整个堆栈跟踪,您可能更喜欢使用davidxxx 建议的自定义ThrowableRenderer 请注意,这仍会将格式化的日志与堆栈跟踪分开发送到 syslog,以避免您可以将此解决方案与上述解决方案结合使用。)

例如:

import org.apache.log4j.DefaultThrowableRenderer;
import org.apache.log4j.spi.ThrowableRenderer;

import java.util.ArrayList;
import java.util.Arrays;

public class CustomThrowableRenderer implements ThrowableRenderer {
    private final DefaultThrowableRenderer defaultRenderer = new DefaultThrowableRenderer();

    @Override
    public String[] doRender(Throwable throwable) {
        String[] defaultRepresentation = defaultRenderer.doRender(throwable);
        String[] newRepresentation = {String.join("|", Arrays.asList(defaultRepresentation))};

        return newRepresentation;
    }
}

然后在你的 log4j.xml 中:

<throwableRenderer class="CustomThrowableRenderer"/>

您可以自定义堆栈跟踪的渲染器。 Log4J 中有两种可用的ThrowableRendererorg.apache.log4j.spi.ThrowableRenderer接口),一种是默认使用的。 因此,使用您想要的格式实现您自己的 ThrowableRenderer,然后在您的配置中设置它。

在 Log4j 1 中,它有效。 永远不要在 Log42 中尝试。 https://logging.apache.org/log4j/1.2/apidocs/org/apache/log4j/PropertyConfigurator.html

ThrowableRenderer 您可以自定义 Throwable 实例在被记录之前转换为 String 的方式。 这是通过指定 ThrowableRenderer 来完成的。 语法是: log4j.throwableRenderer=fully.qualified.name.of.rendering.class log4j.throwableRenderer.paramName=paramValue 就像,log4j.throwableRenderer=org.apache.log4j.EnhancedThrowableRenderer

而不是仅仅将异常传递给记录器(例如log.error(e) ),首先将堆栈跟踪转换为字符串并记录该字符串。

这个问题最受好评的答案有几种简单的方法可以将堆栈跟踪转换为字符串。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM