解决ELK日志被截断的问题

问题1

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

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")

posted @ 2024-04-15 22:27  strongmore  阅读(67)  评论(0编辑  收藏  举报