1. 程式人生 > >基於Java8的日誌類實現

基於Java8的日誌類實現

在程式設計師列印日誌是一個常見的需求,為此Java提供了內建的Logger類來實現,然而Logger類雖然比較好用,但是它還需要我們自己構造訊息體,如果我們利用StackTrace來自動新增呼叫資訊的話,不論是否當前Log級別是否被允許,這些程式碼都會被執行,顯然在生產環境下,這種情況是需要儘量避免的。為了解決這個問題,我們有兩種解決方案,其一是擴充套件Java的Logger類,判斷當前Log級別允許時再通過StackTrace來取得呼叫資訊,其二就是利用Java8新引入函式式介面,來實現這一功能。

首先,我們需要定義一個通用的日誌類,程式碼如下所示:

/**
 * 採用Java8函式式介面的日誌類
 * @author 閆濤 2016.06.12
 *
 */
public class AppLogger {
	public static void log(LogLevel logLevel, Supplier<String> supplier) {
		if (logLevel.getLogLevel() >= LOG_LEVEL.getLogLevel()) {
			String msg = supplier.get();
			StackTraceElement[] stes = new Exception().getStackTrace();
			StackTraceElement caller = stes[1];
			String methodName = caller.getMethodName(); 
			String className = caller.getClassName();
			String lineNumber = "" + caller.getLineNumber();
			System.out.println(className + "." + methodName + "(" + lineNumber + "):" + msg);
		}
	}
	
	/**
	 * 日誌級別列舉型別定義
	 * @author 閆濤 2016.06.12
	 *
	 */
	public static enum LogLevel {
		TRACE(1), DEBUG(2), INFO(3), WARNING(4), ERROR(5);
		private int logLevel = 0;
		private LogLevel(int logLevel) {
			this.logLevel = logLevel;
		}
		public int getLogLevel() {
			return logLevel;
		}
	}
	
	public static LogLevel LOG_LEVEL = LogLevel.INFO;
}
在上面的程式碼中,我們首先定義了一個LogLevel的列舉型別,定義應用中會用到的日誌級別。接著,我們定義一個靜態變數LOG_LEVEL來儲存當前的日誌級別,只有要求列印日誌的級別大於或等於本級別時,才會列印相應的內容。

在日誌函式中,我們首先判斷日誌級別是否大於或等於我們定義的允許級別,如果小於則不做任何處理。如果大於,首先通過StackTrace來取出呼叫者的類名、方法名和行數,然後與要列印的訊息進行合併,列印到控制檯中。

在程式中需要列印日誌時,只需進行如下的呼叫:

AppLogger.log(AppLogger.LogLevel.INFO, ()->"需要列印的訊息");

其會打印出類似如下的內容:

com.haisijia.hxll.simulator.VendorDemo.test(59):需要列印的訊息

如果程式部署到生產環境,只需把LOG_LEVEL的值提高到ERROR級別,就可以避免日誌列印所帶來的效能降低了。同時,還可以動態改變LOG_LEVEL,來臨時除錯一些BUG。