本文将介绍JDK中的Logging API在Java程序中的使用,并在后面附带了一个创建HTML logger的例子
目录
- 概述
-
- Java中的Logging
- 最佳实践
- 样例
- 与讨论
- 文章
1. Overview
JDK中有Java Logging API。通过logger您不仅可以将日志信息集中到一个文件中来报告错误,而且可以在日志中添加辅助信息。这个Logging API允许您充分定制,十分灵活。
包 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,例如:
-
ConsoleHandler: 将log信息写到Console
-
FileHandler: 将log信息写到文件中
超过INFO(包含INFO)的信息将自动被写入到Console中。
1.5. Formatter
每个Handler的输出都可以使用一个formatter来配置
已有的formatter:
-
SimpleFormatter 将所有的log信息以文本格式编排
-
XMLFormatter 生成XML格式的log信息
您还可以自定义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 line class MyHtmlFormatter extends Formatter { // This method is called for every log records public String format(LogRecord rec) { StringBuffer buf = new StringBuffer(1000); // Bold any levels >= WARNING buf.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 created public 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 closed public 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. 示例
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 line class MyHtmlFormatter extends Formatter { // This method is called for every log records public String format(LogRecord rec) { StringBuffer buf = new StringBuffer(1000); // Bold any levels >= WARNING buf.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 created public 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 closed public 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 Logger Logger logger = Logger.getLogger(""); logger.setLevel(Level.INFO); fileTxt = new FileHandler("Logging.txt"); fileHTML = new FileHandler("Logging.html"); // Create txt Formatter formatterTxt = new SimpleFormatter(); fileTxt.setFormatter(formatterTxt); logger.addHandler(fileTxt); // Create HTML Formatter formatterHTML = 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 refactor private final static Logger LOGGER = Logger.getLogger(UseLogger.class .getName()); public void writeLog() { // Set the LogLevel to Severe, only severe Messages will be written LOGGER.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 written LOGGER.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(); } }