一、JUL(Java util Logging)初步學習
JUL是Java原生的日誌框架,很多項目在沒有配置日誌(slf4j或者log4j)時會默認使用jul作爲最後的日誌實現
Java Logging Technology–java日誌簡介
Logger的大致處理流程
1.Loggers:被稱爲記錄器,應用程序通過獲取Logger對象,調用其API來發布日誌信息。Logger通常是應用程序訪問日誌系統的入口程序。
2.Appenders:也被稱爲Handlers,每個Logger都會關聯一組Handlers,Logger會將日誌交換關聯Handlers處理,由Handlers負責將日誌做記錄,Handlers在此是一個抽象,其具體的實現決定了日誌記錄的位置可以是控制檯、文件、網絡上的其他日誌服務或者操作系統日誌等。
3.Layouts:也被稱爲Formatters,它負責對日誌事件中的數據進行轉化和格式化,Layouts決定了數據在一條日誌記錄中的最終形式。
4.level:每條日誌的消息都有一個關聯的日誌級別。該級別粗略指導了日誌消息的重要性和緊迫,我可以將level和loggers,Appenders做關聯以便於我們過濾消息。
5.Filters:過濾器,根據需要定製那些信息會被記錄,哪些信息會被放過
創建Logger對象
// 爲指定子系統查找或創建一個 logger。
static Logger getLogger(String name)
// 爲指定子系統查找或創建一個 logger。
static Logger getLogger(String name, String resourceBundleName)
注意:name是Logger的名稱,當名稱相同時候,同一個名稱的Logger只創建一個。
// 1. 快速入門
@Test
public void testQuick() throws Exception{
// 1.獲取日誌記錄器對象
Logger logger = Logger.getLogger("LoggerDemo.JULTest");
// 2.日誌記錄輸出
logger.info("hello jul");
// 通用方法進行日誌記錄
logger.log(Level.INFO,"info msg");
// 通過佔用符 方式輸出變量值
String name = "com.jul";
Integer age = 13;
logger.log(Level.INFO,"用戶信息:{0},{1}",new Object[]{name,age});
}
Logger的級別
在進行信息的記錄時,依信息程序的不同,會設定不同等級的信息輸出。Java log比log4j的級別詳細,全部定義在java.util.logging.Level裏面。Java的一個日誌級別對應一個整數值,Level有9個內置的級別,分別是:
類型 |
對應的整數 |
OFF |
最大整數( Integer. MAX_VALUE) |
SEVERE |
1000(最高值) |
WARNING |
900 |
INFO |
800 |
CONFIG |
700 |
FINE |
500 |
FINER |
400 |
FINEST |
300(最低值) |
ALL |
最小整數(Integer. MIN_VALUE) |
此外,級別OFF是用來關閉日誌記錄,級別ALL是啓用所有消息的日誌記錄。
logger默認的級別是INFO,比INFO更低的日誌將不顯示。
// 2. 日誌級別
@Test
public void testLogLevel() throws Exception{
// 1.獲取日誌記錄器對象
Logger logger = Logger.getLogger("LoggerDemo.JULTest");
// 2.日誌記錄輸出
logger.severe("severe");
logger.warning("warning");
logger.info("info");//jul默認的日誌級別info
logger.config("config");
logger.fine("fine");
logger.finer("finer");
logger.finest("finest");
}
// 3. 自定義日誌級別
@Test
public void testLogConfig() throws Exception{
// 1.獲取日誌記錄器對象
Logger logger = Logger.getLogger("LoggerDemo.JULTest");
// 關閉系統默認配置
logger.setUseParentHandlers(false);
// 自定義配置日誌級別
// 創建ConsolHandler
ConsoleHandler consoleHandler = new ConsoleHandler();
// 創建簡答格式轉換對象
SimpleFormatter simpleFormatter = new SimpleFormatter();
// 進行關聯
consoleHandler.setFormatter(simpleFormatter);
logger.addHandler(consoleHandler);
// 配置日誌具體級別Level.ALL表示顯示所有的信息,所有這一次的執行結果可顯示所有等級的信息。如果要關閉所有的信息,可以設定爲Level.OFF。
logger.setLevel(Level.ALL);
consoleHandler.setLevel(Level.ALL);
// 場景FileHandler文件輸出
FileHandler fileHandler = new FileHandler("/logs/jul.log");
// 進行關聯
fileHandler.setFormatter(simpleFormatter);
logger.addHandler(fileHandler);
// 2.日誌記錄輸出
logger.severe("severe");
logger.warning("warning");
logger.info("info");//jul默認的日誌級別info
logger.config("config");
logger.fine("fine");
logger.finer("finer");
logger.finest("finest");
}
// 4. Logger對象父子關係 子級繼承父級
@Test
public void testLogParent() throws Exception{
Logger logger1 = Logger.getLogger("com.jultest");
Logger logger2 = Logger.getLogger("com");
// 關閉日誌默認選項
logger2.setUseParentHandlers(false);
// 測試
System.out.println(logger1.getParent() == logger2);
// 所有日誌記錄器的頂級父元素LogManager$RootLogger@3b22cdd0,name: ""
System.out.println("logger2 parent:"+logger2.getParent()+",name:"+logger2.getParent().getName());
// 自定義配置日誌級別
// 創建ConsolHandler
ConsoleHandler consoleHandler = new ConsoleHandler();
// 創建簡答格式轉換對象
SimpleFormatter simpleFormatter = new SimpleFormatter();
// 進行關聯
consoleHandler.setFormatter(simpleFormatter);
logger2.addHandler(consoleHandler);
// 配置日誌具體級別
logger2.setLevel(Level.ALL);
consoleHandler.setLevel(Level.ALL);
// 2.日誌記錄輸出
logger1.severe("severe");
logger1.warning("warning");
logger1.info("info");//jul默認的日誌級別info
logger1.config("config");
logger1.fine("fine");
logger1.finer("finer");
logger1.finest("finest");
}
二、JUL日誌原理解析:
1.初始化LogManager:LogManager加載logging.properties配置;添加Logger到LogManager
2.從單例LogManager獲取Logger
3.設置級別Level,並指定日誌記錄LogRecord
4.Filter提供了日誌級別之外更細粒度的區別
5.Handlers是用來處理日誌輸出位置,Java SE實現了5個Handler:
1) java.util.logging.ConsoleHandler 以System.err輸出日誌。
2) java.util.logging.FileHandler 將信息輸出到文件。
3) java.util.logging.StreamHandler以指定的OutputStream實例輸出日誌。
4) java.util.logging.SocketHandler將信息通過Socket傳送至遠程主機。
5) java.util.logging.MemoryHandler將信息暫存在內存中。
6.Formatter爲格式化LogRecords提供支持。一般來說,每個Handler都有關聯的Formatter。Formatter接受LogRecord,並將它轉換爲一個字符串。
默認提供了兩種Formatter:
1.java.util.logging.SimpleFormatter:標準日誌格式,就是我們通常在啓動一些諸如 Tomcat、 JBoss之類的服務器的時候經常能在控制檯下看到的那種形式。
2.java.util.logging.XMLFormatter:XML形式的日誌格式,如果爲Logger添加了一個newXMLFormatter(),那麼就會以XML形式輸出,不過更常用的是使用上面介紹的FileHandler輸出到XML文件中。
FileHandler的默認格式是java.util.logging.XMLFormatter,而ConsolerHandler的默認格式是java.util.logging.SimpleFormatter,可以使用Handler實例的setFormatter()方法來設定信息的輸出格式。
FileHandler的Formatter設定爲SimpleFormatter,則輸出的日誌文件內容就是簡單的文字信息,打開文件後會發現與命令行模式下看到的信息內容相同。
<--
java默認log配置文件:
這樣在maven項目中快速使用jul日誌,項目根目錄新建配置文件logging.properties
-->
handles = java.util.logging.ConsoleHandler,java.util.logging.FileHandler
<--.level 是針對所有handler與包的根日誌級別;ConsoleHandler.level是使用Console這個handler的logger級別-->
.level = ALL
java.util.logging.FileHandler.pattern = /logs/java%u.log
java.util.logging.FileHandler.limit = 50000
java.util.logging.FileHandler.count = 1
java.util.logging.FileHandler.formatter = java.util.logging.XMLFormatter
java.util.logging.ConsoleHandler.level = ALL
java.util.logging.ConsoleHandler.formatter = java.util.logging.SimpleFormatter
// 5. 加載自定義配置文件測試Demo
@Test
public void testLogProperties() throws Exception{
// 讀取配置文件,通過類加載器
InputStream ins = JULTest.class.getClassLoader().getResourceAsStream("logging.properties");
// 創建LogManager
LogManager logManager = LogManager.getLogManager();
// 通過LogManager加載配置文件
logManager.readConfiguration(ins);
// 創建日誌記錄器
Logger logger = Logger.getLogger("LoggerDemo.JULTest");
// 2.日誌記錄輸出
logger.severe("severe");
logger.warning("warning");
logger.info("info");//jul默認的日誌級別info
logger.config("config");
logger.fine("fine");
logger.finer("finer");
logger.finest("finest");
// 創建日誌記錄器
Logger logger2 = Logger.getLogger("test");
// 2.默認日誌記錄輸出和讀取配置文件日誌記錄輸出的比較
logger2.severe("severe test ");
logger2.warning("warning test ");
logger2.info("info test ");//jul默認的日誌級別info
logger2.config("config test ");
logger2.fine("fine test ");
logger2.finer("finer test ");
logger2.finest("finest test ");
}
java.util.logging包中類的關係圖如下: