我正在使用log4j syslog appender并注意到当发生异常时,appender会将堆栈跟踪中的每个条目都写为新行。
有没有办法配置它,以便整个堆栈跟踪将作为一行而不是多行?
答案 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中有两个可用ThrowableRenderer
(org.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)
请参见james' answer。
与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有几种简单的方法可以将堆栈跟踪转换为字符串。