解決ELK日誌被截斷的問題

strongmore發表於2024-04-15

問題1

解決ELK日誌被截斷的問題
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class TestLogger {
    
    private static Logger logger = LoggerFactory.getLogger(TestLogger.class);

    public static void main(String[] args) {
        String test = "<xml>\n" +
                "   <appid>wx123456789</appid>\n" +
                "   <mch_id>123456789</mch_id>\n" +
                "   <nonce_str>6cefdb308e1e2e8aabd48cf79e546a02</nonce_str>\n" +
                "   <out_refund_no>123456789</out_refund_no>\n" +
                "   <out_trade_no>123456789</out_trade_no>\n" +
                "   <refund_fee>1</refund_fee>\n" +
                "   <total_fee>1</total_fee>\n" +
                "   <transaction_id>123456789</transaction_id>\n" +
                "   <sign>FE56DD4AA85C0EECA82C35595A69E153</sign>\n" +
                "</xml>";
        logger.info("test a,{}", test);
    }
}

當我們的 message 中包含換行符時,會被 ELK 截斷,影響我們排查問題。可以透過清除換行符來解決此問題。

String test2 = test.replaceAll("\r\n|\r|\n", "");

問題2

解決ELK日誌被截斷的問題
public class TestLogger2 {

    private static Logger logger = LoggerFactory.getLogger(TestLogger2.class);

    public static void main(String[] args) {
        logger.error("test abc", new RuntimeException("test"));
    }
}

異常資訊被截斷,解決方法如下

public class TestLogger3 {

    private static Logger logger = LoggerFactory.getLogger(TestLogger3.class);

    public static void main(String[] args) {
        String test3 = stackTraceToString(new RuntimeException("test3"));
        logger.error("test3 {}", test3);
    }

    /**
     * 參考 {@link io.netty.util.internal.ThrowableUtil#stackTraceToString(java.lang.Throwable)}
     */
    private static String stackTraceToString(Throwable cause) {
        ByteArrayOutputStream out = new ByteArrayOutputStream();
        PrintStream pout = new PrintStream(out);
        cause.printStackTrace(pout);
        pout.flush();
        try {
            return out.toString();
        } finally {
            try {
                out.close();
            } catch (IOException ignore) {
            }
        }
    }
}

我們自己將異常堆疊資訊轉換為字串,就莫名其妙解決了這個問題,具體原因未找到。

Logback 內部透過 ThrowableProxyConverter 的 convert() 方法將異常轉換為字串。

Logback 的 convert() 方法和我們自己的 cause.printStackTrace(pout) 底層最終使用的換行符都是 System.getProperty("line.separator")

解決ELK日誌被截斷的問題

相關文章