問題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")。