002_Java日志
1. Level對象
1.1. Level類定義了一組可用來控制日志輸出的標(biāo)準(zhǔn)日志級別。日志Level對象是有序的, 并且是通過有序的整數(shù)來指定。在給定的級別上啟用日志記錄也就啟用了所有較高級別的日志記錄。
1.2. 各級別按降序排列如下:
- SEVERE(最高值)
- WARNING
- INFO
- CONFIG
- FINE
- FINER
- FINEST(最低值)
1.3. 此外, 還有一個級別OFF, 可用來關(guān)閉日志記錄, 使用級別ALL啟用所有消息的日志記錄。
1.4. public static final Level OFF是一個可用于關(guān)閉日志記錄的特殊級別。此級別初始化為Integer.MAX_VALUE。
1.5. public static final Level SEVERE是指示嚴(yán)重失敗的消息級別。通常, SEVERE消息應(yīng)該描述相當(dāng)重要的事件, 這些事件會阻止正常程序的執(zhí)行。它們對于最終用戶和系統(tǒng)管理員來說應(yīng)該是很容易理解的。此級別初始化為1000。
1.6. public static final Level WARNING是指示潛在問題的消息級別。通常, WARNING消息應(yīng)該描述最終用戶或系統(tǒng)管理員感興趣的事件或者那些指示潛在問題的事件。此級別初始化為900。
1.7. public static final Level INFO是報告消息的消息級別。通常, INFO消息被寫入到控制臺或與之相當(dāng)?shù)牡胤健R虼? INFO 級別應(yīng)該只用于相當(dāng)重要的, 對于最終用戶和系統(tǒng)管理員有意義的消息。此級別初始化為800。
1.8. public static final Level CONFIG是用于靜態(tài)配置消息的消息級別。CONFIG消息提供各種靜態(tài)配置信息, 并協(xié)助調(diào)試那些與特定配置有關(guān)的問題。例如, CONFIG消息可能包括CPU類型、圖形色深、GUI外觀等等。此級別初始化為700。
1.9. public static final Level FINE是提供跟蹤信息的消息級別。FINE、FINER和FINEST都適合用于相對詳細(xì)的跟蹤。三個級別的準(zhǔn)確意義在不同子系統(tǒng)間有所不同, 但是通常來說, FINEST 應(yīng)該用于最為詳細(xì)的輸出, FINER 用于不太詳細(xì)的輸出, FINE用于極少量(且非常重要)的消息。通常, FINE級別應(yīng)該用于開發(fā)人員比較感興趣的信息, 而這些開發(fā)人員對特定子系統(tǒng)則沒有特別的興趣。
FINE消息可能包括諸如次要的(可恢復(fù)的)失敗之類的信息。指示潛在性能問題的信息也可以作為FINE記錄到日志。此級別初始化為500。
1.10. public static final Level FINER指示一條相當(dāng)詳細(xì)的跟蹤消息。在默認(rèn)情況下, 對于輸入、返回或拋出異常的日志記錄調(diào)用在此級別進(jìn)行跟蹤。此級別初始化為400。
1.11. public static final Level FINEST指示一條最詳細(xì)的跟蹤消息。此級別初始化為300。
1.12. public static final Level ALL指示應(yīng)該記錄所有消息。此級別初始化為Integer.MAX_VALUE。
2. Logger對象
2.1. Logger對象用來記錄特定系統(tǒng)或應(yīng)用程序組件的日志消息。一般使用圓點分隔的層次名稱空間來命名Logger。如java.net或javax.swing。
2.2. public static Logger getLogger(String name)方法, 為指定子系統(tǒng)查找或創(chuàng)建一個logger。如果已經(jīng)創(chuàng)建了具有給定名稱的logger, 則返回該logger。否則創(chuàng)建一個新的logger。
Logger logger1 = Logger.getLogger(MyLogger.class.getName()); // 第一次是創(chuàng)建 Logger logger2 = Logger.getLogger(MyLogger.class.getName()); // 第二次是查找 System.out.println(logger1 == logger2); // 輸入true2.3. public void setLevel(Level newLevel) throws SecurityException方法, 設(shè)置日志級別, 指定此logger記錄的消息級別。將級別低于此值的消息丟棄。可以使用級別值Level.OFF來關(guān)閉日志記錄。如果將Logger的級別設(shè)置為null, 那么它的有效級別繼承自父Logger, 這可以通過其父Logger一直沿樹向上遞歸得到。
2.4. 日志消息被轉(zhuǎn)發(fā)到已注冊的Handler對象, 該對象可以將消息轉(zhuǎn)發(fā)到各種目的地, 包括控制臺、文件、OS日志等等。
2.5. public void severe(String msg)記錄一條SEVERE消息。如果當(dāng)前對于SEVERE消息級別而言logger是啟用的, 那么將給定的消息轉(zhuǎn)發(fā)到所有已注冊的輸出Handler對象。
2.6. public void warning(String msg)記錄一條WARNING消息。如果當(dāng)前對于WARNING消息級別而言logger是啟用的, 那么將給定的消息轉(zhuǎn)發(fā)到所有已注冊的輸出Handler對象。
2.7. public void info(String msg)記錄一條INFO消息。如果當(dāng)前對于INFO消息級別而言logger是啟用的, 那么將給定的消息轉(zhuǎn)發(fā)到所有已注冊的輸出Handler對象。
2.8. public void config(String msg)記錄一條CONFIG消息。如果當(dāng)前對于CONFIG消息級別而言logger是啟用的, 那么將給定的消息轉(zhuǎn)發(fā)到所有已注冊的輸出Handler對象。
2.9. public void fine(String msg)記錄一條FINE消息。如果當(dāng)前對于FINE消息級別而言logger是啟用的, 那么將給定的消息轉(zhuǎn)發(fā)到所有已注冊的輸出Handler對象。
2.10. public void finer(String msg)記錄一條FINER消息。如果當(dāng)前對于FINER消息級別而言logger是啟用的, 那么將給定的消息轉(zhuǎn)發(fā)到所有已注冊的輸出Handler對象。
2.11. public void finest(String msg)記錄一條FINEST消息。如果當(dāng)前對于FINEST消息級別而言logger是啟用的, 那么將給定的消息轉(zhuǎn)發(fā)到所有已注冊的輸出Handler對象。
3. 簡單例子
3.1. 代碼
package com.rjbd.loggerjvm;import java.util.logging.Level; import java.util.logging.Logger;public class MyLogger {public static void main(String[] args) {Logger logger1 = Logger.getLogger(MyLogger.class.getName());Logger logger2 = Logger.getLogger(MyLogger.class.getName());System.out.println(logger1 == logger2); // 輸入truelogger1.setLevel(Level.ALL);logger1.severe("severe level in java util logging Logger");logger1.warning("warning level in java util logging Logger");logger1.info("info level in java util logging Logger");logger1.config("config level in java util logging Logger");logger1.fine("fine level in java util logging Logger");logger1.finer("finer level in java util logging Logger");logger1.finest("finest level in java util logging Logger");} }3.2. 運行結(jié)果
4. Handler對象
4.1. Handler繼承結(jié)構(gòu), 常用的ConsoleHandler和FileHandler
4.2. 在我們的MyLogger例子中, 我們并沒有為logger1對象設(shè)置Handler對象, 然而控制臺卻打印了日志, 這是因為默認(rèn)的創(chuàng)建了一個最頂層的日志RootLogger, 而且RootLogger的日志級別是INFO, 同時RootLogger的處理器是ConsoleHandler, 這就是為什么控制臺打印出了info及其更高級別的日志。
4.3. 創(chuàng)建Logger對象的時候設(shè)置了它的parent為RootLogger對象
4.4. RootLogger的ConsoleHandler創(chuàng)建過程
4.5. 讀取配置文件
5. FileHandler例子
5.1. 代碼
package com.rjbd.loggerjvm;import java.io.IOException; import java.util.logging.FileHandler; import java.util.logging.Level; import java.util.logging.Logger;public class MyHandler {public static void main(String[] args) {Logger logger = Logger.getLogger(MyHandler.class.getName());logger.setLevel(Level.ALL);logger.getParent().getHandlers()[0].setLevel(Level.ALL);try {FileHandler fileHandler = new FileHandler("MyLogger.log");logger.addHandler(fileHandler);} catch (SecurityException | IOException e) {e.printStackTrace();}logger.severe("severe level in java util logging Logger");logger.warning("warning level in java util logging Logger");logger.info("info level in java util logging Logger");logger.config("config level in java util logging Logger");logger.fine("fine level in java util logging Logger");logger.finer("finer level in java util logging Logger");logger.finest("finest level in java util logging Logger");} }5.2. 運行結(jié)果
5.3. 生成MyLogger.log文件
6. Formatter對象
6.1. Formatter為格式化LogRecords提供支持。
6.2. Formatter繼承結(jié)構(gòu), 自帶了XMLFormatter和SimpleFormatter
6.3. 一般來說, 每個日志記錄Handler都有關(guān)聯(lián)的Formatter。Formatter接受LogRecord, 并將它轉(zhuǎn)換為一個字符串。FileHandler默認(rèn)使用XMLFormatter, ConsoleHandler默認(rèn)使用SimpleFormatter。我們也可以自定義Formatter。
7. 自定義Formatter例子
7.1. 代碼
package com.rjbd.loggerjvm;import java.io.IOException; import java.text.SimpleDateFormat; import java.util.Date; import java.util.EnumSet; import java.util.Iterator; import java.util.logging.FileHandler; import java.util.logging.Formatter; import java.util.logging.Level; import java.util.logging.LogRecord; import java.util.logging.Logger;public class MyFormatter {public static void main(String[] args) {Logger logger = Logger.getLogger(MyFormatter.class.getName());logger.setLevel(Level.ALL);try {FileHandler fh = new FileHandler("MyFormatterLogger.log");logger.addHandler(fh);SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");String lineSperator = System.getProperty("line.separator");fh.setFormatter(new Formatter() {@Overridepublic String format(LogRecord record) {String time = "[" + sdf.format(new Date(record.getMillis())) + "]";String qualifiedMethod = "[" + record.getLoggerName() + ":" + record.getSourceMethodName() + "]";String levelNameMsg = "[" + LevelToLocalName.get(record.getLevel().intValue()) + ": " + record.getMessage() + "]";return "[" + time + " " + qualifiedMethod + " " + levelNameMsg + "]" + lineSperator;}});} catch (SecurityException | IOException e) {e.printStackTrace();}logger.severe("severe level in java util logging Logger");logger.warning("warning level in java util logging Logger");logger.info("info level in java util logging Logger");logger.config("config level in java util logging Logger");logger.fine("fine level in java util logging Logger");logger.finer("finer level in java util logging Logger");logger.finest("finest level in java util logging Logger");} }enum LevelToLocalName {SEVERE(Level.SEVERE.intValue(), "嚴(yán)重"),WARNING(Level.WARNING.intValue(), "警告"),INFO(Level.INFO.intValue(), "信息"),CONFIG(Level.CONFIG.intValue(), "配置"),FINE(Level.FINE.intValue(), "詳細(xì)"),FINER(Level.FINER.intValue(), "較詳細(xì)"),FINEST(Level.FINEST.intValue(), "非常詳細(xì)");private int level;private String name;LevelToLocalName(int level, String name) {this.level = level;this.name = name;}public int getLevel() {return level;}public String getName() {return name;}public static String get(int level) {EnumSet<LevelToLocalName> es = EnumSet.allOf(LevelToLocalName.class);Iterator<LevelToLocalName> it = es.iterator();while (it.hasNext()) {LevelToLocalName type = it.next();if (level == type.getLevel()) {return type.getName();}}return "";}}7.2. 運行結(jié)果
總結(jié)
以上是生活随笔為你收集整理的002_Java日志的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 001_日志系统的架构模型
- 下一篇: 015_JavaMail