基於Java8的日誌類實現
阿新 • • 發佈:2019-01-30
在程式設計師列印日誌是一個常見的需求,為此Java提供了內建的Logger類來實現,然而Logger類雖然比較好用,但是它還需要我們自己構造訊息體,如果我們利用StackTrace來自動新增呼叫資訊的話,不論是否當前Log級別是否被允許,這些程式碼都會被執行,顯然在生產環境下,這種情況是需要儘量避免的。為了解決這個問題,我們有兩種解決方案,其一是擴充套件Java的Logger類,判斷當前Log級別允許時再通過StackTrace來取得呼叫資訊,其二就是利用Java8新引入函式式介面,來實現這一功能。
首先,我們需要定義一個通用的日誌類,程式碼如下所示:
在上面的程式碼中,我們首先定義了一個LogLevel的列舉型別,定義應用中會用到的日誌級別。接著,我們定義一個靜態變數LOG_LEVEL來儲存當前的日誌級別,只有要求列印日誌的級別大於或等於本級別時,才會列印相應的內容。/** * 採用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; }
在日誌函式中,我們首先判斷日誌級別是否大於或等於我們定義的允許級別,如果小於則不做任何處理。如果大於,首先通過StackTrace來取出呼叫者的類名、方法名和行數,然後與要列印的訊息進行合併,列印到控制檯中。
在程式中需要列印日誌時,只需進行如下的呼叫:
AppLogger.log(AppLogger.LogLevel.INFO, ()->"需要列印的訊息");
其會打印出類似如下的內容:
com.haisijia.hxll.simulator.VendorDemo.test(59):需要列印的訊息
如果程式部署到生產環境,只需把LOG_LEVEL的值提高到ERROR級別,就可以避免日誌列印所帶來的效能降低了。同時,還可以動態改變LOG_LEVEL,來臨時除錯一些BUG。