開發人員應該用logger.fine( obj )
來取代System.out.println( obj )
;
當調用 System.out.println 時, 實際上生成了下面的日誌消息:logger.fine();
JDK的日誌系統有以下幾個主要的類和概念:
日誌記錄器 Logger
- 記錄器負責暫存日誌數據到內存中
- 只有當某條日誌的級別高於記錄器設定的閾值時,此條日誌纔會被記錄器記錄到內存。
- Logger可以自行指定處理器/日誌級別的閾值
日誌處理器 LogHandler
- 負責將暫存在內存中的記錄寫入到File(FileHandler)或者Console(ConsoleHandler)控制檯
- 只有當某條日誌記錄的級別高於處理器設定的閾值時,此條日誌記錄纔會被寫入到File或者控制檯
- 默認情況下,日誌記錄器會將記錄發送到ConsoleHandler中,並由他輸出到System.err流中(閾值默認爲INFO)
- 默認情況下,日誌記錄器還會將日誌記錄發送到自己的處理器的父處理器中,而最終的父處理器有一個ConsoleHandler父處理器會再次對日誌處理(寫到文件或者哪裏)。
- 由於默認會有父處理器會再次對記錄進行處理,而我們並不想將一個記錄處理兩次,因此一般需要設置
logger.setUseParentHandlers(false)
- jdk提供的日誌處理器:FileHandler、ConsoleHandler、SocketHandler-可以指定主機和端口。
- FileHandler默認將日誌寫到用戶主目錄的javan.log文件中。
日誌管理器 管理日誌配置 LogManager**
負責管理JDK日誌系統的配置信息,比如日誌級別、使用哪個日誌處理器等。
日誌配置文件
- JRE默認的日誌配置文件是:jre/lib/logging.properties
可以在啓動命令中,更改日誌配置文件的位置:
java -Djava.util.logging.config.file=configfilepath mainClass
日誌管理器LogManager會在JVM啓動過程中初始化,在main方法調用之前完成。
但也也可以在main方法中更改日誌配置文件的位置:System.setProperty("java.util.logging.config.file",configfilepath)
,這會觸發LogManager.readConfiguration()來重新初始化日誌管理器。
日誌配置項
可以在日誌配置文件中設置如下配置項
com.mycomp.myapp.level=FINE
java.util.logging.ConsoleHandler.level=Level.INFO
java.util.logging.FileHandler.level=Level.ALL
java.util.logging.FileHandler.append=false (如果設置爲true的話,那麼這個Handler會將自己處理的記錄追加到已經存在的日誌文件的尾部,如果多個應用程序副本使用同一個日誌文件,應設爲true。)
java.util.logging.FileHandler.limit=50000(每個日誌文件的最大字節數)
java.util.logging.FileHandler.count=1(共可創建多少個日誌文件——默認爲1個。即當日志記錄逐漸增多,1個文件的大小已經達到limit後,會清掉舊的日誌記錄,仍在這1個文件中保存新的記錄。如果設置爲10,則當10個日誌文件都已經滿了後,會刪除掉原來的第0個日誌文件,創建一個新的與0同名的日誌文件,然後新的日誌記錄寫到此文件中)
java.util.logging.FileHandler.pattern=%h/java%u.log(日誌文件名的模式,一般改成%h/myapp.log,/是路徑中的文件夾分隔符)
java.util.logging.FileHandler.filter=無(使用什麼過濾器類)
java.util.logging.FileHandler.formatter=java.util.logging.XMLFormatter(日誌記錄的格式器)
日誌文件名模式變量:
變量名 | 描述 |
---|---|
%h | 系統屬性user.home的值 |
%t | 系統臨時目錄 |
%u | 用於解決衝突的唯一編號,如果多個應用程序使用同一個日誌文件名,應該加%u,以便每一個應用程序副本都有自己唯一的日誌副本 |
%g | 循環日誌記錄生成的數值 |
%% | %字符 |
示例
Logger logger = Logger.getLogger("應用程序的根包全限定路徑名"); // 獲得一個日誌記錄器,如果不存在在創建。後續所有類都可以通過Logger.getLogger("應用程序的根包全限定路徑名")直接獲得並使用這個logger去記錄日誌。
logger.setLevel(Levle.FINE); // 設置記錄器的日誌級別的閾值
Handler handler = new ConsoleHandler();
handler.setLevel(Level.FINE);
logger.setHandler(handler);
logger.setUseParentHandler(false);