摘要:所有低于級別的消息記錄將會被忽略。構造函數,創建一個與有關的構造函數,創建一個,記錄消息到指定文件。這個構造函數用來創建一個對象這個方法來自類,通過它設置。該對象是全局的,用來維護一組共享狀態和日志服務。
Jdk Logging 解析原文鏈接
原作者:Rohit Joshi
譯者:smallclover
個人翻譯,水平有限,如有錯誤歡迎指出,謝謝!
在本文中,我們將討論關于Java的日志(logging)功能。日志,用簡單的話來說就是記錄應用程序的活動。日志通常被用于存儲異常(exceptions)、信息(information)、警告(warnings)的消息,這些消息可能會出現在程序的整個執行過程。日志在程序員調式(debug)程序的過程中會有所幫助。
Java 包(package)java.util.logging與日志記錄的功能有關。這個包由一些用于日志功能的類(class)和接口(interface)組成。系統使用Logger對象(object)來記錄消息。
這個Logger對象會被分配一個LogRecord對象,該LogRecord對象存儲了記錄的消息。這個LogRecord對象會被轉發到所有的handler,再由handler分派給Logger對象。logger和handler可以視需要使用一個與它們有關聯的過濾器(Filter)來過濾日志消息。然后,handler會發布這些被日志記錄的消息到外部的系統。
讓我們從這個包中一些比較重要的類開始。
1.Logger and Level創建一個Logger類的logger對象來記錄消息。logger對象會要求使用者提供一個名稱和一組用于設置記錄消息的等級的方法。雖然你可以提供任何一個名字到logger,但是建議使用包和類名來創建logger。
Level類提供7種日志級別
SEVERE (最高級別)
WARNING
INFO
CONFIG
FINE
FINER
FINEST (最低級別)
在Level中所有的級別(level)都被定義成靜態常量字段(static final field)。你能使用任何一個級別,然后根據這些級別來記錄消息。另外,它還提供了一個level OFF 可以關閉日志記錄,一個level All用于打開所有級別的日志。
我們看一個關于如何創建和使用logger的示例。
LoggerExample.java
01 package com.javacodegeeks.corejava.util.logging; 02 03 import java.io.IOException; 04 import java.util.logging.Level; 05 import java.util.logging.Logger; 06 07 public class LoggerExample { 08 09 private static final Logger LOGGER = Logger.getLogger(LoggerExample.class.getName()); 10 public static void main(String[] args) throws SecurityException, IOException { 11 12 LOGGER.info("Logger Name: "+LOGGER.getName()); 13 14 LOGGER.warning("Can cause ArrayIndexOutOfBoundsException"); 15 16 //An array of size 3 17 int []a = {1,2,3}; 18 int index = 4; 19 LOGGER.config("index is set to "+index); 20 21 try{ 22 System.out.println(a[index]); 23 }catch(ArrayIndexOutOfBoundsException ex){ 24 LOGGER.log(Level.SEVERE, "Exception occur", ex); 25 } 26 27 28 } 29 30 }
如果我們運行以上代碼,我們將得到如下結果:
1 Jun 08, 2014 1:19:30 PM com.javacodegeeks.corejava.util.logging.LoggerExample main 2 INFO: Logger Name: com.javacodegeeks.corejava.util.logging.LoggerExample 3 Jun 08, 2014 1:19:31 PM com.javacodegeeks.corejava.util.logging.LoggerExample main 4 WARNING: Can cause ArrayIndexOutOfBoundsException 5 Jun 08, 2014 1:19:31 PM com.javacodegeeks.corejava.util.logging.LoggerExample main 6 SEVERE: Exception occur 7 java.lang.ArrayIndexOutOfBoundsException: 4 8 at com.javacodegeeks.corejava.util.logging.LoggerExample.main(LoggerExample.java:22)
在上面這個示例中,我們使用getLogger靜態方法(static method)創建了一個logger對象。然后,我們記錄了不同級別的日志消息。為了闡述Logger的使用我們也嘗試拋出了ArrayIndexOutOfBoundsException。
讓我們看一看在本例中使用的方法。
Logger.getLogger(String name):該方法通過傳遞的name參數來創建或者發現一個logger。
void info(String msg):該實例方法用于記錄INFO級別的日志消息,但是前提是當前的logger能夠使用INFO級別的日志消息,否則該級別的日志消息將會被忽略。
void warning(String msg): 該實例方法用于記錄WARNING級別的日志消息,但是前提是當前的logger能夠使用INFO級別的日志消息,否則該級別的日志消息將會被忽略。
void config(String msg): 該實例方法用于記錄CONFIG級別的日志消息,但是前提是當前的logger能夠使用INFO級別的日志消息,否則該級別的日志消息將會被忽略。
void log(Level level, String msg, Object param1):該方法根據傳遞的日志級別來記錄消息,同時傳遞的參數還有一個object。當你想存儲一個對象在日志中的時候你可使用這個方法。正如我們上面的示例一樣,我們記錄了一個SEVERE級別的exception object。
請注意,INFO級別是logger的默認級別。所有低于INFO級別的消息記錄將會被忽略。正如你所看到的那樣,WARNING級別的消息記錄被忽略了,并沒有被打印在控制臺上。(此處原文可能有誤)
譯者注:這里原文可能有錯誤,首先WARNING的級別是高于INFO級別的,其次WARNING級別的日志的確打印在控制臺上。所以,譯者認為這里應該是CONFIG級別。請讀者注意。
2.HandlerHandler是日志框架的組件之一,它負責打印日志消息到目標目的地。這個目的地可以是控制臺(console)也可以是文件(file)。Handler獲得一個LogRecord對象形式的日志消息,并輸出到目標目的地。一個Logger可以關聯一個或者多個Handler,最后將日志消息轉發給所有的Handler。Handler在Java 包 java.util.logging中是一個抽象類,同時它也是各種Handler的父類。
在Java中內置4種handler。
ConsoleHandler: ConsoleHandler 記錄所有的System.in的日志消息,默認情況下,Logger是與此Handler相關聯的。
FileHandler: FileHandler 記錄所有的來自特定的文件或者一組文件集合的日志消息。
StreamHandler: StreamHandler會發布所有的日志消息到一個OutputStream.
SocketHandler: SocketHandler會發布LogRecords到一個網絡連接流中。
MemoryHandler: 它是用來保持LogRecords內存緩沖區。如果緩沖區滿了,新的LogRecords會覆蓋舊的LogRecords。
HandlerExample.java
01 package com.javacodegeeks.corejava.util.logging; 02 03 import java.io.IOException; 04 import java.util.logging.ConsoleHandler; 05 import java.util.logging.FileHandler; 06 import java.util.logging.Handler; 07 import java.util.logging.Level; 08 import java.util.logging.Logger; 09 10 public class HandlerExample { 11 12 private static final Logger LOGGER = Logger.getLogger(LoggerExample.class.getName()); 13 public static void main(String[] args) { 14 15 Handler consoleHandler = null; 16 Handler fileHandler = null; 17 try{ 18 //Creating consoleHandler and fileHandler 19 consoleHandler = new ConsoleHandler(); 20 fileHandler = new FileHandler("./javacodegeeks.log"); 21 22 //Assigning handlers to LOGGER object 23 LOGGER.addHandler(consoleHandler); 24 LOGGER.addHandler(fileHandler); 25 26 //Setting levels to handlers and LOGGER 27 consoleHandler.setLevel(Level.ALL); 28 fileHandler.setLevel(Level.ALL); 29 LOGGER.setLevel(Level.ALL); 30 31 LOGGER.config("Configuration done."); 32 33 //Console handler removed 34 LOGGER.removeHandler(consoleHandler); 35 36 LOGGER.log(Level.FINE, "Finer logged"); 37 }catch(IOException exception){ 38 LOGGER.log(Level.SEVERE, "Error occur in FileHandler.", exception); 39 } 40 41 LOGGER.finer("Finest example on LOGGER handler completed."); 42 43 } 44 45 }
如果我們運行以上代碼,我們將會得到以下結果:
1 Jun 08, 2014 1:43:19 PM com.javacodegeeks.corejava.util.logging.HandlerExample main 2 CONFIG: Configuration done.
該示例還會在項目的根目錄下生成日志文件javacodegeeks.log。
該文件包含以下記錄:
01 02 0304 05 152014-06-08T13:43:19 061402215199326 070 08com.javacodegeeks.corejava.util.logging.LoggerExample 09CONFIG 10com.javacodegeeks.corejava.util.logging.HandlerExample 11main 121 13Configuration done. 1416 262014-06-08T13:43:19 171402215199376 181 19com.javacodegeeks.corejava.util.logging.LoggerExample 20FINE 21com.javacodegeeks.corejava.util.logging.HandlerExample 22main 231 24Finer logged 2527 372014-06-08T13:43:19 281402215199376 292 30com.javacodegeeks.corejava.util.logging.LoggerExample 31FINER 32com.javacodegeeks.corejava.util.logging.HandlerExample 33main 341 35Finest example on LOGGER handler completed. 36
在該示例中,我們通過FileHandler 和ConsoleHandler記錄日志消息。
我們將討論上面的示例。
ConsoleHandler():構造函數,創建一個與system.err有關的ConsoleHandler
FileHandler(String pattern):構造函數,創建一個FileHandler,記錄消息到指定文件。
void addHandler(Handler handler):該實例方法來自類Logger,分配一個handler給logger對象。你也可以分配多個handler給一個logger對象。就像該示例一樣,我們分配了ConsoleHandler 和 FileHandler給了一個logger對象。
void setLevel(Level newLevel):Logger和Handler類都有該方法,logger對象通過它來設置指定的日志級別,規定哪些級別的消息可以被記錄。消息級別小于指定的級別的將會被忽略。
void removeHandler(Handler handler):該方法會移除與logger對象相關聯的handler,一旦該handler被移除,它將沒有能力發布任何日志消息。在該示例中,我們移除了ConsoleHandler之后,接下來所有的日志消息將不會被打印在控制臺。
void finer(String msg):該示例方法用來記錄FINER級別的消息,如果當前允許FINER級別的日志消息則記錄,否則忽略。
該日志消息通過FileHandler 發布,在上面的示例中被發布為XML格式。該格式是FileHandler 的默認格式,我們可以改變該handler 的格式。
在下一節中,我們將討論關于Formatter類和它的使用。
3.FormatterFormatter 用于格式化LogRecord。每個handler會關聯一個formatter。Java提供了兩個內置的超類formatter:SimpleFormatter 和 XMLFormatter。讓我們來看一些示例:
FormatterExample.java
01 package com.javacodegeeks.corejava.util.logging; 02 03 import java.io.IOException; 04 import java.util.logging.Formatter; 05 import java.util.logging.FileHandler; 06 import java.util.logging.Handler; 07 import java.util.logging.Level; 08 import java.util.logging.Logger; 09 import java.util.logging.SimpleFormatter; 10 11 public class FormatterExample { 12 13 private static final Logger LOGGER = Logger.getLogger(LoggerExample.class.getName()); 14 public static void main(String[] args) { 15 16 Handler fileHandler = null; 17 Formatter simpleFormatter = null; 18 try{ 19 20 // Creating FileHandler 21 fileHandler = new FileHandler("./javacodegeeks.formatter.log"); 22 23 // Creating SimpleFormatter 24 simpleFormatter = new SimpleFormatter(); 25 26 // Assigning handler to logger 27 LOGGER.addHandler(fileHandler); 28 29 // Logging message of Level info (this should be publish in the default format i.e. XMLFormat) 30 LOGGER.info("Finnest message: Logger with DEFAULT FORMATTER"); 31 32 // Setting formatter to the handler 33 fileHandler.setFormatter(simpleFormatter); 34 35 // Setting Level to ALL 36 fileHandler.setLevel(Level.ALL); 37 LOGGER.setLevel(Level.ALL); 38 39 // Logging message of Level finest (this should be publish in the simple format) 40 LOGGER.finest("Finnest message: Logger with SIMPLE FORMATTER"); 41 }catch(IOException exception){ 42 LOGGER.log(Level.SEVERE, "Error occur in FileHandler.", exception); 43 } 44 } 45 46 }
如果我們運行以上代碼,我們將得到以下結果:
1 Jun 08, 2014 4:57:02 PM com.javacodegeeks.corejava.util.logging.FormatterExample main 2 INFO: Finnest message: Logger with DEFAULT FORMATTER
該示例也會在項目的根目錄下生成一個日志文件:javacodegeeks.formatter.log。
在上面的示例中,我們使用SimpleFormatter以一種簡單的,可讀的格式打印LogRecord。請注意在設置handler的格式為 SimpleFormatter之前,我們的消息會發布到一個XML格式的文件中。因為FileHandler的默認格式是XMLFormatter。同時還要注意這個LogRecord也會被發布到控制臺,因為 ConsoleHandler 和 Logger是默認關聯的。
SimpleFormatter():這個構造函數用來創建一個SimpleFormatter對象.
void setFormatter(Formatter newFormatter):這個方法來自handler類,handler通過它設置formatter。
3.FilterFilter接口(interface)位與java.util.logging包下。 Handler通過它來控制消息的記錄。每一個Logger和Handler可以選擇一個Filter。Filter 有一個isLoggable方法,該方法返回一個boolean值。在Logger或者Handler發布消息之前會調用此方法,如果返回值為true就發布消息,否則就忽略。
FilterExample.java
01 package com.javacodegeeks.corejava.util.logging; 02 03 import java.util.logging.Filter; 04 import java.util.logging.LogRecord; 05 import java.util.logging.Logger; 06 07 public class FilterExample implements Filter{ 08 09 private static final Logger LOGGER = Logger.getLogger(LoggerExample.class.getName()); 10 public static void main(String[] args) { 11 //Setting filter FilterExample 12 LOGGER.setFilter(new FilterExample()); 13 //Since this message string does not contain the word important. Despite of being the Level SEVERE this will be ignored 14 LOGGER.severe("This is SEVERE message"); 15 //This will get published 16 LOGGER.warning("This is important warning message"); 17 18 } 19 20 // This method will return true only if the LogRecord object contains the message which contains the word important 21 @Override 22 public boolean isLoggable(LogRecord record) { 23 if(record == null) 24 return false; 25 26 String message = record.getMessage()==null?"":record.getMessage(); 27 28 if(message.contains("important")) 29 return true; 30 31 return false; 32 } 33 34 }
如果我們運行以上代碼,我們將得到以下的結果:
1 Jun 08, 2014 5:13:46 PM com.javacodegeeks.corejava.util.logging.FilterExample main 2 WARNING: This is important warning message
boolean isLoggable(LogRecord record):該方法來自Filter的接口,它會檢查LogRecord是否可以發布。
void setFilter(Filter newFilter): 該方法設置一個 Filter 控制 Logger的輸出。
5.Configuration你可以通過一個配置文件把配置的屬性提供給Logger。這有助于你移除配置代碼并且提供一種更加簡單的方法在不改變代碼的情況下一次又一次的更改配置。通過類LogManager我們可以使用這種靈活的方式。
ConfigurationExample.java
01 package com.javacodegeeks.corejava.util.logging; 02 03 import java.io.FileInputStream; 04 import java.io.IOException; 05 import java.util.logging.Level; 06 import java.util.logging.LogManager; 07 import java.util.logging.Logger; 08 09 public class ConfigurationExample { 10 11 private static final LogManager logManager = LogManager.getLogManager(); 12 private static final Logger LOGGER = Logger.getLogger("confLogger"); 13 static{ 14 try { 15 logManager.readConfiguration(newFileInputStream("./javacodegeeks.properties")); 16 } catch (IOException exception) { 17 LOGGER.log(Level.SEVERE, "Error in loading configuration",exception); 18 } 19 } 20 public static void main(String[] args) { 21 LOGGER.fine("Fine message logged"); 22 } 23 }
該示例讀取了包含以下屬性的屬性文件:
屬性文件
1 handlers=java.util.logging.ConsoleHandler 2 .level=ALL 3 java.util.logging.ConsoleHandler.level=ALL 4 java.util.logging.ConsoleHandler.formatter=java.util.logging.SimpleFormatter 5 confLogger.level=ALL
如果運行以上代碼,我們將獲得以下結果:
1 Jun 08, 2014 5:23:25 PM com.javacodegeeks.corejava.util.logging.ConfigurationExample main 2 FINE: Fine message logged
讓我們討論該示例的代碼和它所配置的屬性。
handlers: 設置所有的logger使用默認的handler。
.level:設置所有logger的默認日志級別,值ALL表示開啟所有級別的日志消息。
java.util.logging.ConsoleHandler.level: 設置所有ConsoleHandler 的默認日志級別為ALL,即對于ConsoleHandler開啟所有級別的日志消息。
java.util.logging.ConsoleHandler.formatter: 設置 ConsoleHandler 的默認格式為SimpleFormatter.
confLogger.level: 設置名稱為confLogger的默認級別為開啟所有的級別的日志消息。
需要注意的是這些屬性都可以在代碼中被覆蓋。
LogManager.getLogManager():該方法是一個靜態方法,用于獲取LogManager對象。該LogManager對象是全局的,用來維護一組共享狀態和日志服務。
void readConfiguration(InputStream ins):該方法被用來重新初始化日志記錄的屬性,通過從stream中重新讀取日志配置,該配置應該符合java.util.Properties的格式
6.Download the source code你可以從這里下載這個示例的源代碼:LoggingExample.zip
失敗是成功之母。
failure is mother of success.
失敗は成功の母。
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/65813.html
摘要:注意,其是在編譯源碼過程中,幫你自動生成的。就是說,將極大減少你的代碼總量。注解和類似,區別在于它會把所有成員變量默認定義為修飾,并且不會生成方法。不同的日志注解總結如下上面是注解,下面是編譯后的代碼參考資料下的安裝以及使用簡介注解介紹 Lombok有什么用 在我們實體Bean中有大量的Getter/Setter方法以及toString, hashCode等可能不會用到,但是某些時候仍...
摘要:定制日志文件簡單的日志配置不能滿足實際項目需求,那可以通過引用定制日志文件的形式達到目的。能根據類路徑下的類庫和配置文件自動配置對應的日志框架。看到這里,相信你對的日志應該有了一個全面的了解。 本節內容基于 Spring Boot 2.0. 你所需具備的基礎 什么是 Spring Boot? Spring Boot 核心配置文件詳解 Spring Boot 開啟的 2 種方式 Spr...
摘要:在年首次發表了這種語言,另外與也是這語言的共同設計者。每種都可以通過配置使用控制臺或者文件輸出日志內容。可以通過是中的一個設置的日志級別。參考文檔新年彩蛋自定義參考指南配置類配置詳解 導讀: 在上篇文章學習到了如何搭建一個簡單的Spring Boot的項目,這篇文章我們主要圍繞Spring Boot的外部化文件展開, 快速開始:外部化配置 首先是一個典型的Spring Boot的項...
摘要:理解在記錄消息中的日志的不同級別是非常重要的。通常來說,當為指定了一個該會包含當前指定級別以及更高級別的日志。,將消息發送至單個一般文件或一個可回滾的文件集合。 本文網大多網絡整理所得,出處太多,不一一列舉 簡介 Java 中的 Logging API 讓 Java 應用可以記錄不同級別的信息,它在debug過程中非常有用,如果系統因為各種各樣的原因而崩潰,崩潰原因可以在日志中清晰地追...
摘要:默認情況下,如果使用,則使用進行日志記錄,還包括適當的路由,以確保使用或的依賴庫都能正確工作。分隔符,用于區分實際日志消息的開始。 26. 日志記錄 Spring Boot為所有內部日志記錄使用Commons Logging,但開放底層日志實現,提供了Java Util Logging、Log4J2和Logback的默認配置,在每種情況下,日志記錄器都被預先配置為使用控制臺輸出,可選的...
閱讀 1344·2023-04-26 00:35
閱讀 2715·2023-04-25 18:32
閱讀 3344·2021-11-24 11:14
閱讀 770·2021-11-22 15:24
閱讀 1417·2021-11-18 10:07
閱讀 6466·2021-09-22 10:57
閱讀 2773·2021-09-07 09:58
閱讀 3565·2019-08-30 15:54