一 简述
java.util.logging是JDK自带的日志记录包。
默认情况下,JDK的LogManager会在JRE目录下的"lib/logging.properties"这个文件中读取配置。
JDK的日志包涉及handler,formatter,level
名词 | 描述 |
handler | 将日志信息记录到指定的流之中,可能是控制台或者是一个文件或者是任意存储区域。 常用实现类 ConsoleHandler, FileHandler, SocketHandler |
formatter | 日志信息格式化类。常用实现类 SimpleFormatter, XMLFormatter |
level | 日志记录级别。 SEVERE(最高值) 、WARNING 、INFO 、CONFIG 、FINE 、FINER 、FINEST(最低值) ALL(记录所有信息) OFF(不记录任何级别信息) |
二 简单Demo
MySimpleFormatter.java
package logging.formatter;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.logging.Level;
import java.util.logging.LogRecord;
import java.util.logging.SimpleFormatter;
public class MySimpleFormatter extends SimpleFormatter{
private SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
private StringBuilder sb = new StringBuilder();
@Override
public synchronized String format(LogRecord record)
{
Level level=record.getLevel();
String time=sdf.format(new Date(record.getMillis()));
String loggerName=record.getLoggerName();
String message=record.getMessage();
this.sb.append("[").append(level).append("]");
this.sb.append(" ").append(time);
this.sb.append(" ").append(loggerName);
this.sb.append(" :").append(message);
this.sb.append("\n");
return sb.toString();
}
}
DefaultStreamHandler.java
package logging.handler;
import java.io.OutputStream;
import java.util.logging.StreamHandler;
public class DefaultStreamHandler extends StreamHandler {
@Override
public synchronized void setOutputStream(OutputStream out)
throws SecurityException {
super.setOutputStream(out);
}
}
CustomLogManager.java
package logging.util;
import java.io.IOException;
import java.io.InputStream;
import java.util.logging.ConsoleHandler;
import java.util.logging.FileHandler;
import java.util.logging.Level;
import java.util.logging.LogManager;
import java.util.logging.Logger;
import logging.formatter.MySimpleFormatter;
import logging.handler.DefaultStreamHandler;
public class CustomLogManager{
static{
LogManager.getLogManager().reset(); // reset the log manager
}
// read the log configuration from outside property file
public static void resetFromPropertyFile(String filePath){
LogManager logManager = LogManager.getLogManager();
InputStream inputStream = CustomLogManagerEditor.class.getClassLoader().getResourceAsStream(filePath);
try {
logManager.readConfiguration(inputStream);
} catch (Exception e) {
throw new RuntimeException("reload log configuration fail: "+e.toString());
}
}
public static Logger getLogger(String name){
Logger logger=Logger.getLogger(name);
logger.setLevel(Level.ALL);
// add console handler
ConsoleHandler consoleHandler=new ConsoleHandler();
consoleHandler.setLevel(Level.FINE);
consoleHandler.setFormatter(new MySimpleFormatter());
logger.addHandler(consoleHandler);
// add file handler
FileHandler fileHandler=null;
try {
fileHandler = new FileHandler("log.log",true);
fileHandler.setLevel(Level.FINE);
fileHandler.setFormatter(new MySimpleFormatter());
logger.addHandler(fileHandler);
} catch (SecurityException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
// add default stream handler
DefaultStreamHandler defaultStreamHandler = new DefaultStreamHandler();
defaultStreamHandler.setLevel(Level.ALL);
defaultStreamHandler.setFormatter(new MySimpleFormatter());
defaultStreamHandler.setOutputStream(System.out);
logger.addHandler(defaultStreamHandler);
return logger;
}
}
logging.properties
#Level的五个等级SEVERE(最高值) 、WARNING 、INFO 、CONFIG 、FINE 、FINER 、FINEST(最低值) 。这个不同于log4j #指定默认logger级别 .level= ALL #为 Handler 指定默认的级别(默认为 Level.INFO)。 java.util.logging.ConsoleHandler.level=FINE # 指定要使用的 Formatter 类的名称(默认为 java.util.logging.SimpleFormatter)。 java.util.logging.ConsoleHandler.formatter=logging.formatter.MySimpleFormatter # 为 Handler 指定默认的级别(默认为 Level.ALL)。 java.util.logging.FileHandler.level=ALL # 指定要使用的 Formatter 类的名称(默认为 java.util.logging.XMLFormatter)。 java.util.logging.FileHandler.formatter=java.util.logging.SimpleFormatter # 指定要写入到任意文件的近似最大量(以字节为单位)。如果该数为 0,则没有限制(默认为无限制)。 java.util.logging.FileHandler.limit=1024000 # 指定有多少输出文件参与循环(默认为 1)。 java.util.logging.FileHandler.count=1 # 为生成的输出文件名称指定一个模式。有关细节请参见以下内容(默认为 "%h/java%u.log")。 java.util.logging.FileHandler.pattern=u.log # 指定是否应该将 FileHandler 追加到任何现有文件上(默认为 false)。 java.util.logging.FileHandler.append=true handlers= java.util.logging.ConsoleHandler,java.util.logging.FileHandler
测试类
Main.java
package logging;
import java.io.IOException;
import java.util.logging.Logger;
import logging.util.CustomLogManager;
public class Main {
public static void main(String[] args) throws SecurityException, IOException {
// CustomLogManager.resetFromPropertyFile("logging/logging.properties");
// Logger logger=Logger.getLogger(Main.class.getName());
Logger logger=CustomLogManager.getLogger(Main.class.getName());
logger.fine("warning test!");
}
}
Note:
CustomLogManagerEditor.getLogger返回的logger拥有三个handler,所以记录日志信息的时候,日志信息会被存储到三个区域【log.log,System.out,System.err】。
当启用CustomLogManagerEditor.resetFromPropertyFile("logging/logging.properties");时,日志信息会被记录到控制台,以及u.log文件。
如果即调用CustomLogManagerEditor.resetFromPropertyFile("logging/logging.properties");又通过CustomLogManagerEditor.getLogger返回的logger记录日志,因为logger有5个handler,所以日志信息会被记录到4个区域【u.log,log.log,System.out,System.err】 其中在System.err中会记录2次。