在 Java 中的日誌語句後面新增換行符號/空白行
1.概述
如果我們曾經盯著一面日誌輸出牆試圖找出問題所在,那麼我們並不孤單。日誌本應讓我們的生活更輕鬆,但它們很快就會變得難以承受,尤其是當條目之間沒有視覺喘息空間時。
我們可以做的一個小而強大的調整是在日誌語句後面加上一個空白行。這聽起來微不足道,但它可以顯著提高日誌的可讀性,特別是當我們偵錯複雜問題時。
在本教程中,我們將探討在 Java 中實現此目的的幾種實用方法以及每種方法的合理性。
2. 快速修復:記錄一個空字串
如果我們使用 SLF4J、Logback 或 Log4j 等日誌框架,最簡單的方法就是記錄一個空白行:
public class LogLineBreakDemo {
private static final Logger logger = LoggerFactory.getLogger(LogLineBreakDemo.class);
public static void main(String[] args) {
logger.info("Start process");
logger.info("");
}
}
以下是此程式碼的輸出:
2025-05-14 10:30:00 INFO LogLineBreakDemo - Start process
2025-05-14 10:30:00 INFO LogLineBreakDemo -
這種方法有效,但有一個警告。空白行仍然獲得時間戳記和日誌等級:
2025-05-14 10:30:00 INFO LogLineBreakDemo -
它使我們的日誌變得混亂,但還有更乾淨的替代方案。讓我們看看它們。
3. 使用System.lineSeparator()
這是一種獨立於平台且優雅的方法,可以直接在日誌訊息中加入換行符:
public class LogLineBreakDemo {
private static final Logger logger = LoggerFactory.getLogger(LogLineBreakDemo.class);
public static void main(String[] args) {
logger.info("Processing done{}", System.lineSeparator());
logger.info("Processing done" + System.lineSeparator());
}
}
有兩種使用System.lineSeparator():
logger.info("Processing done{}", System.lineSeparator());
logger.info("Processing done" + System.lineSeparator());
兩者都記錄我們的訊息,然後是換行符,而不需要額外的空日誌呼叫:
2025-05-14 10:30:00 INFO LogLineBreakDemo - Processing done
2025-05-14 10:30:00 INFO LogLineBreakDemo - Processing done
但這裡有一個問題:為什麼我們不能使用\n
?**我們可以使用\n
,但它是 Unix 特有的。在 Windows 上,換行符號是\r\n
。**透過使用System.lineSeparator()
,我們可以確保無論程式碼在何處運行,日誌格式都是正確的。
4. 使用System.getProperty(“line.separator”)
它的工作原理與以前的方法相同:
public class LogLineBreakDemo {
private static final Logger logger = LoggerFactory.getLogger(LogLineBreakDemo.class);
public static void main(String[] args) {
String newline = System.getProperty("line.separator");
logger.info("Processing started" + newline);
logger.info("Processing ended");
}
}
讓我們看看輸出:
2025-05-14 10:45:00 INFO LogLineBreakDemo - Processing started
2025-05-14 10:45:00 INFO LogLineBreakDemo - Processing ended
但自 Java 7 以來, System.lineSeparator()
更短、更清晰,更受歡迎。
5. 日誌格式中的全域空白行
如果我們希望每個日誌條目後面都有一個空白行,最乾淨的方法是在日誌框架層級使用自訂日誌模式進行配置。
如果我們使用帶有**Logback的SLF4J** (這是 Spring Boot 中的預設設定),我們需要更新logback.xml
檔案:
<configuration>
<appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<!-- Adds a blank line after each log message -->
<pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n%n</pattern>
</encoder>
</appender>
<root level="info">
<appender-ref ref="CONSOLE" />
</root>
</configuration>
如果我們使用帶有**Log4j2的 SLF4J,**則我們將如下更新log4j2.xml
:
<Configuration status="WARN">
<Appenders>
<Console name="Console" target="SYSTEM_OUT">
<PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n%n"/>
</Console>
</Appenders>
<Loggers>
<Root level="info">
<AppenderRef ref="Console"/>
</Root>
</Loggers>
</Configuration>
為了在每個日誌訊息後插入一個空行,我們透過更新日誌模式佈局來修改logback.xml
和log4j2.xml
,以使用%n%n
包含兩個換行符。
在logback.xml
中,我們將<encoder>
元素內的模式改為以%msg%n%n
結尾。
類似地,在log4j2.xml
中,我們也更新<PatternLayout>
模式屬性以包含%msg%n%n
。
%n
符號使用系統行分隔符號插入與平台無關的換行符,重複兩次會導致日誌條目之間出現額外的空白行。這個小小的改變提高了日誌的可讀性,特別是在控制台或日誌檔案中,透過直觀地分離每個日誌訊息,使其更容易掃描或偵錯。
6. 使用System.out.println()
列印空白行
我們總是可以拋出一個System.out.println()
來建立一個空白行。但是將System.out
與 SLF4J 或 Log4j 等日誌框架混合使用通常不是一個好主意。不建議這麼做。以下是解決這一問題的幾個原因:
- 它不經過我們的日誌管道
- 我們失去了時間戳記、日誌等級和結構化日誌的優勢
- 在生產環境中追蹤和匯總日誌更加困難
雖然我們可以根據需要使用它進行快速調試,但我們應該在實際程式碼中避免使用它。
7. 結論
在本文中,我們探討了在不同的記錄器庫中新增換行符的各種方法。在日誌語句後面加上換行符號只是一個小小的改動,但卻能帶來很大的不同。它有助於直觀地分離事件,使日誌更易於理解,特別是當我們深入生產偵錯時。
與往常一樣,本文中提供的程式碼可在 GitHub 上找到。