如何正確使用log4j


 

如何正確使用log4j?

關鍵字: 如何正確使用log4j?

 

Java Web開發的過程中,通過會采用輸出log的方式來進行調試,產品上線之后,也通常使用log來記錄系統的運行狀態。最簡單的輸出log的方式就是使用System.out.println(String msg)和System.err.println(String msg),然而這種方式的弊端是顯而易見的,例如:
1. 調試期輸出log的代碼,在上線運行前需要注釋掉,否則可能會影響系統性能或者造成日志文件過於龐大。當出現問題需要跟蹤的時候,又需要修改代碼,刪除注釋符以打開這些debug的log,非常不方便;
2. 所有的業務的log都會輸出到一個文件中去,查看起來很不方便。
 
    多虧apache開源社區為所有Java開發者提供了Log4j這個非常弓雖大的log工具,把我們從 維護log的繁重工作中解脫了出來。Log4j可能通過配置文件實現多logger,每個logger可以有不同的輸出文件、輸出格式和log級別,具體 細節我就不再贅述,不了解的同學可以參考相關的文檔或者示例代碼。
 
    這里主要總結幾點Log4j使用過程中的常見問題和注意事項,閱讀一下內容之前,下面的文章將假設你已經有一定的Log4j使用經驗了。
 
  • 1. 獲取Logger實例的方法:
protected static final Logger logger = Logger.getLogger("logger_name");
private static final Logger logger = Logger.getLogger("logger_name");
 
還有一個獲取Logger的方法:
Logger.getLogger(Class clazz);
 
1.1 為什么要加“static”?
    因為同一個logger name對應唯一的Logger實例,而Logger.getLogger方法在從logger容器中取logger的過程中,有一個步驟被加了同步鎖, 這就造成了如果在多線程的競爭環境中頻繁地調用getLogger操作,有可能會造成堵塞。而且這種操作是沒有價值的,所以使用static來保證需要需 用Logger的類所有的對象共享一個Logger的引用,並且只獲取一次就可以了。
1.2 為什么要加“final”
    防止多logger同時使用時,Logger引用不小心被賦值,這是一個良好的編程習慣。
1.3 Logger.getLogger(String loggerName)與Logger.getLogger(Class clazz)有什么區別?
    本質上是一樣的,Logger.getLogger(Class clazz)方法實際上是調用了Logger.getLogger(clazz.getName())來獲取Logger的。
1.4 log4j配置文件中沒有配置logger_name對應的logger怎么辦?
    如果沒有logger_name對應的配置,則Logger.getLogger方法返回默認的logger。
 
  •  2. Logger共有6個log級別,按優先級由低到高排序分別是:
    TRACE < DEBUG < INFO < WARN < ERROR < FATAL
    他們分別對應Logger的trace, debug, info, warn, error和fatal方法進行輸出,但是我們通常只使用debug、info和error這三個最常用的級別。運行時的log輸出級別可以通過更改log4j配置文件來進行配置,就免去了注釋掉debug代碼的尷尬。
 
  • 3. 輸出log的正確方式:
    if (logger.isInfoEnabled()) {
        logger.info("User " + userId + " is using app " + appId);
    }
3.1 為什么要加上logger.isInfoEnabled()?
    直接使用logger.info("User " + userId + " is using app " + appId)來輸出log,也能夠達到log級別為INFO或在INFO以下時才輸出:("User " + userId + " is using app " + appId),因為logger.info方法內部有判斷輸出級別的代碼。但是在進入logger.info函數之前,("User " + userId + " is using app " + appId) 這個表達式已經通過運算拼接成了一個字符串;而如果事先使用 if (logger.isInfoEnabled())進行判斷,那么當log級別在INFO以上時,就能省去上述的字符串操作,在高並發和復雜log信息拼 接的情況下,使用這種標准的方法輸出log能夠省去不小的系統開銷。另外,如果構造log信息的過程需要大量字符串操作,建議使用 StringBuilder來完成字符串拼接。
3.2 ERROR及其以上級別的log信息是一定會被輸出的,所以只有logger.isDebugEnabled和logger.isInfoEnabled方法,而沒有logger.isErrorEnabled方法。
 
  • 4. debug、info、error等輸出log的方法是線程安全的,請放心使用。
 
  • 5. log有風險,輸出需謹慎!由於輸出log過程需要進行磁盤操作,且log4j為了保證log輸出過程的線程安全性而使用同步鎖,就使得輸出log成為很耗時的操作,所以log信息一定要言簡意賅,不要輸出一些無用的log。
 
    以上為我個人的使用經驗,歡迎大家指教和補充。
 
    最后,祝願log4j給大家帶來更加愉快的開發體驗。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM