jubincn

导航

Java Logging API - Tutorial

本文将介绍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. Overview

1.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,例如:

  • 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. 示例

您可以在项目“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 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();
	}
}


posted on 2012-06-26 16:50  jubincn  阅读(360)  评论(0编辑  收藏  举报