原文地址:http://www.vogella.com/articles/Logging/article.html
Java Logging
本文將介紹JDK中的Logging API在Java程式中的使用,並在後面附帶了一個建立HTML logger的例子
目錄
-
1.
概述
-
-
1.1. Java中的Logging
-
1.2. 建立一個logger
-
1.3. Log等級
-
1.4. Handler
-
1.5. Formatter
-
1.6. Log Manager
-
1.7. 最佳實務
-
2.
範例
-
3. 致謝
-
4. 問題與討論
-
5. 相關
文章
1. Overview1.1. Java中的Logging
JDK中有Java Logging API。通過logger您不僅可以將日誌資訊集中到一個檔案中來報告錯誤,而且可以在日誌中添加輔助資訊。這個Logging API允許您充分定製,十分靈活。
1.2. 建立一個logger
包 java.util.logging提供了日誌的功能,可以使用類似於下面的代碼來建立一個logger:
import java.util.logging.Logger;private final static Logger LOGGER = Logger.getLogger(MyClass.class .getName());
1.3. Level
Log的等級反映了問題的嚴重程度。Level類用於決定哪些資訊被寫入到log中。下面是一個按嚴重程度的降序排列的Log Level:
SEVERE (highest)
WARNING
INFO
CONFIG
FINE
FINER
FINEST
除此之外,您還可以使用OFF或ALL這兩個level來關閉log或開啟所有log。
下面這行代碼是將logger設定為記錄INFO層級:
LOGGER.setLevel(Level.INFO);
1.4. Handler
每個logger可以設定多個Handler。
Handler的作用是接收logger的資訊,並將其以合適的格式發送到合適的地方。
一個Handler可以用setLevel(Level.OFF)來關閉,用setLevel(...)開啟。
JDK提供了幾個標準的handler,例如:
超過INFO(包含INFO)的資訊將自動被寫入到Console中。
1.5. Formatter
每個Handler的輸出都可以使用一個formatter來配置
已有的formatter:
您還可以自訂Formatter,下面的這個樣本Formatter可以將log資訊用html的格式封裝:
package logging;import java.text.SimpleDateFormat;import java.util.Date;import java.util.logging.Formatter;import java.util.logging.Handler;import java.util.logging.Level;import java.util.logging.LogRecord;//This custom formatter formats parts of a log record to a single lineclass MyHtmlFormatter extends Formatter{// This method is called for every log recordspublic String format(LogRecord rec){StringBuffer buf = new StringBuffer(1000);// Bold any levels >= WARNINGbuf.append("<tr>");buf.append("<td>");if (rec.getLevel().intValue() >= Level.WARNING.intValue()){buf.append("<b>");buf.append(rec.getLevel());buf.append("</b>");} else{buf.append(rec.getLevel());}buf.append("</td>");buf.append("<td>");buf.append(calcDate(rec.getMillis()));buf.append(' ');buf.append(formatMessage(rec));buf.append('\n');buf.append("<td>");buf.append("</tr>\n");return buf.toString();}private String calcDate(long millisecs){SimpleDateFormat date_format = new SimpleDateFormat("MMM dd,yyyy HH:mm");Date resultdate = new Date(millisecs);return date_format.format(resultdate);}// This method is called just after the handler using this// formatter is createdpublic String getHead(Handler h){return "<HTML>\n<HEAD>\n" + (new Date()) + "\n</HEAD>\n<BODY>\n<PRE>\n"+ "<table border>\n "+ "<tr><th>Time</th><th>Log Message</th></tr>\n";}// This method is called just after the handler using this// formatter is closedpublic String getTail(Handler h){return "</table>\n </PRE></BODY>\n</HTML>\n";}}
1.6. Log Manager
log manager的職責是建立和管理logger,並負責維護log配置。
使用LogManager.setLevel(String name, Level level)方法,我們可以為一個包或一組包設定logging level。例如,我們可以將所有logger的logging
level設為Level.FINE:
LogManager.getLogManager().setLevel("logging", Level.FINE)
1.7. Best Practices
使用被logged的那個類的名稱為logger命名是一種很好的方法,這種方法可以使程式員更好地查看日誌和管理logger,同時,這也是Logging API推薦的一種方式。
2. 樣本您可以在項目“de.vogella.logger”中找到這個例子:
建立你自己的formatter:
package logging;import java.text.SimpleDateFormat;import java.util.Date;import java.util.logging.Formatter;import java.util.logging.Handler;import java.util.logging.Level;import java.util.logging.LogRecord;//This custom formatter formats parts of a log record to a single lineclass MyHtmlFormatter extends Formatter{// This method is called for every log recordspublic String format(LogRecord rec){StringBuffer buf = new StringBuffer(1000);// Bold any levels >= WARNINGbuf.append("<tr>");buf.append("<td>");if (rec.getLevel().intValue() >= Level.WARNING.intValue()){buf.append("<b>");buf.append(rec.getLevel());buf.append("</b>");} else{buf.append(rec.getLevel());}buf.append("</td>");buf.append("<td>");buf.append(calcDate(rec.getMillis()));buf.append(' ');buf.append(formatMessage(rec));buf.append('\n');buf.append("<td>");buf.append("</tr>\n");return buf.toString();}private String calcDate(long millisecs){SimpleDateFormat date_format = new SimpleDateFormat("MMM dd,yyyy HH:mm");Date resultdate = new Date(millisecs);return date_format.format(resultdate);}// This method is called just after the handler using this// formatter is createdpublic String getHead(Handler h){return "<HTML>\n<HEAD>\n" + (new Date()) + "\n</HEAD>\n<BODY>\n<PRE>\n"+ "<table border>\n "+ "<tr><th>Time</th><th>Log Message</th></tr>\n";}// This method is called just after the handler using this// formatter is closedpublic String getTail(Handler h){return "</table>\n </PRE></BODY>\n</HTML>\n";}}
初始化logger
package logging;import java.io.IOException;import java.util.logging.FileHandler;import java.util.logging.Formatter;import java.util.logging.Level;import java.util.logging.Logger;import java.util.logging.SimpleFormatter;public class MyLogger {static private FileHandler fileTxt;static private SimpleFormatter formatterTxt;static private FileHandler fileHTML;static private Formatter formatterHTML;static public void setup() throws IOException {// Create LoggerLogger logger = Logger.getLogger("");logger.setLevel(Level.INFO);fileTxt = new FileHandler("Logging.txt");fileHTML = new FileHandler("Logging.html");// Create txt FormatterformatterTxt = new SimpleFormatter();fileTxt.setFormatter(formatterTxt);logger.addHandler(fileTxt);// Create HTML FormatterformatterHTML = new MyHtmlFormatter();fileHTML.setFormatter(formatterHTML);logger.addHandler(fileHTML);}}
使用logger
package logging;import java.io.IOException;import java.util.logging.Level;import java.util.logging.Logger;public class UseLogger {// Always use the classname, this way you can refactorprivate final static Logger LOGGER = Logger.getLogger(UseLogger.class.getName());public void writeLog() {// Set the LogLevel to Severe, only severe Messages will be writtenLOGGER.setLevel(Level.SEVERE);LOGGER.severe("Info Log");LOGGER.warning("Info Log");LOGGER.info("Info Log");LOGGER.finest("Really not important");// Set the LogLevel to Info, severe, warning and info will be written// Finest is still not writtenLOGGER.setLevel(Level.INFO);LOGGER.severe("Info Log");LOGGER.warning("Info Log");LOGGER.info("Info Log");LOGGER.finest("Really not important");}public static void main(String[] args) {UseLogger logger = new UseLogger();try {MyLogger.setup();} catch (IOException e) {e.printStackTrace();throw new RuntimeException("Problems with creating the log files");}logger.writeLog();}}