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

时间:2016-07-20 16:43:17

标签: java log4j syslog

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

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

4 个答案:

答案 0 :(得分:2)

我正在使用以下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>

答案 1 :(得分:0)

您可以自定义堆栈跟踪的渲染器。 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

答案 2 :(得分:0)

Log4j2

请参见james' answer

Log4j v1

james mentioned一样,最好的方法是使用带有%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>

davidxxx proposed an alternate solution,以自定义throwableRenderer。尽管这可行,但需要更多工作。这也不是最佳解决方案,因为日志消息和堆栈跟踪将作为两个单独的系统日志消息发送。比每行单独发送一条消息要好,但幅度不大。

如果您仍然想要这样做,则以下代码可能会有用:

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("\n", Arrays.asList(defaultRepresentation))};

        return newRepresentation;
    }
}

然后在您的log4j.xml中:

<throwableRenderer class="CustomThrowableRenderer"/>

答案 3 :(得分:-1)

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

最受欢迎的答案to this question有几种简单的方法可以将堆栈跟踪转换为字符串。