簡體   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