目录
1.1 Logger的Formatter,为格式化LogRecords提供支持
2.1 XMLFormatter继承了Formatter, 并重写了其中的format(), getHead(), getTail()方法
2.2 思考:如何重写(自定义) 自己的formatter?
2.3 思考:如果要求在SimpleFormatter的基础上,在getHead()和getTail() 部分做一些改动的话,如何实现?
1. 背景概念
1.1 Logger的Formatter,为格式化LogRecords提供支持
一般每个日志记录Handler都有关联的Formatter,可以用默认的,也可以自定义formatter.
Formatter接受LogRecord, 即日志内容,并将它转换为一定格式的字符串。
1.2 常用的几种Formatter格式
java.util.logging.Formatter
java.util.logging.SimpleFormatter
java.util.logging.XMLFormatter
1.3 LogRecord介绍
LogRecord(Level level, String msg):用给定级别和消息值构造LogRecord。
LogRecord对象:用于在日志框架和单个日志Handler之间传递日志请求。
1.4 XMLFormatter简介
有些formatter(如XML Formatter)需要围绕一组格式化记录来包装头部和尾部字符串。
可以使用getHead(Handler h)和getTail(Handler h)方法来获得这些字符串。
2. 详解Formatter
2.1 XMLFormatter继承了Formatter, 并重写了其中的format(), getHead(), getTail()方法
如何控制这几个方法的执行?
答:由logger系统默认定义好的。(这个逻辑就类似于Junit4中默认设定并控制@Test方法的执行,无需用户去人为控制)
2.2 思考:如何重写(自定义) 自己的formatter?
(1)定义一个类MyFormatter,继承Formatter。
重写format(), getHead(), getTail()方法。注意各个方法的入参。
public class MyFormatter extends Formatter {
@Override
public String format(LogRecord record) {
return "******" + record.getLevel() + ":" + record.getMessage() + "******" + "\r\n";
}
@Override
public String getHead(Handler h){
return "start here \r\n";
}
@Override
public String getTail(Handler h){
return "end here \r\n";
}
}
(2)测试类(入口类)
public class TestMyFormatter {
public static void main(String[] args) throws IOException {
Logger log = Logger.getLogger("MyLogger1"); //Logger对象
log.setLevel(Level.INFO);
FileHandler fileHandler = new FileHandler("C:/log111.log");
fileHandler.setFormatter(new MyFormatter()); //handler中,设置formatter
log.addHandler(fileHandler); //logger中,添加handler
log.info("hhh"); //在不同的日志等级方法基础上,传不同的信息值
log.info("sss");
log.warning("jjj");
fileHandler.close(); //关闭handler
}
}
(3)结果:
控制台输出(控制台还是使用默认的SimpleFormatter):
九月 14, 2021 3:43:35 下午 MyLog.TestMyFormatter main
信息: hhh
九月 14, 2021 3:43:36 下午 MyLog.TestMyFormatter main
信息: sss
九月 14, 2021 3:43:36 下午 MyLog.TestMyFormatter main
警告: jjj
日志文件log111.log中的内容(使用了自定义的formatter格式和内容):
start here
******INFO:hhh******
******INFO:sss******
******WARNING:jjj******
end here
2.3 思考:如果要求在SimpleFormatter的基础上,在getHead()和getTail() 部分做一些改动的话,如何实现?
这里有一个容易绕不出来的坑就是:不是所有自定义的formatter都要直接继承Formatter!
如果是要求在SimpleFormatter的基础上自定义formatter, 那自定义formatter类时,让其直接继承SimpleFormatter,根据需求重写SimpleFormatter的部分方法即可。
3. 问题补充
(1)formatter和record:
filehandler 和 consolehandler 输出的数据形式是不同的,这种不同的形式的展示,就是通过formatter来实现的。
简言之,logrecord 就是数据集合,formatter是展现的形式。
即:从logrecord中拿到的各种数据值,在formatter里进行填空: format(LogRecord record) 。
(2)jdk默认的logging.properties中默认设置的fomatter:控制台是SimpleFormatter, 文件是XMLFormatter。
如果在工程中要更改控制台默认的formatter, 除了在代码中设置之外,还需要在logging.properties中把默认的控制台的formatter关掉(注释掉),否则代码中的更改设置不生效:
ConsoleHandler ch=new ConsoleHandler();
ch.setFormatter(new MyFormater());