JUL全称Java util logging
入门案例
先来看着入门案例,直接创建logger对象,然后传入日志级别和打印的信息,就能在控制台输出信息。
可以看出只输出了部分的信息,其实默认的日志控制器是有一个默认的日志级别的,默认就是info 所以最多优先级比info低的都不能输出。
@Test
public void testQuick() {
System.out.println("hello");
//传入唯一标识,一般为当前的类名
Logger logger= Logger.getLogger("com.itheima.julTest");
logger.severe("severe logger message");//logger.log(Level.severe,"logger message");
logger.warning("warning logger message");
logger.info("info logger message"); //默认日志级别
logger.config("config logger message");
logger.fine("fine logger message");
logger.finer("finer logger message");
logger.finest("finest logger message");
}
自定义日志级别
设置handler,设置handler和logger的级别
- Handler:日志处理器,每个Logger会关联持有多个Handler,Logger会把日志交给Handler进行处理,由Handler负责日志记录。Handler在这里是一个抽象,其具体实现决定了日志输出的位置,比如控制台,文件等
也就是说,通过使用不同的handler可以将日志输出到文件或者控制台。
下面这个地方:
//logger设置不使用父logger的handler,不然日志会重复记录。此处后面会讲
logger.setUseParentHandlers(false);如果不设置,将会输出两边日志信息
@Test
public void loggerLevel() {
//创建日志记录器,传入参数是日志记录器的名称
Logger logger = Logger.getLogger("com.itheima");
//创建一个输出到控制台的handler
ConsoleHandler consoleHandler = new ConsoleHandler();
//设置handler的日志级别为ALL,输出全部日志。
consoleHandler.setLevel(Level.ALL);
//把handler添加到logger中
logger.addHandler(consoleHandler);
//logger也设置日志级别为ALL
logger.setLevel(Level.ALL);
//logger设置不使用父logger的handler,不然日志会重复记录。此处后面会讲
logger.setUseParentHandlers(false);
//记录severe级别信息
logger.severe("severe信息");
//记录warning级别信息
logger.warning("warning信息");
logger.info("info信息");
logger.config("config信息");
logger.fine("fine信息");
logger.finer("finer信息");
logger.finest("finest信息");
}
父子关系
一开始以为是继承,后来发现并不是,只是通过设置可以复用一些配置
默认父子关系通过名称的层级关系来确定的。层级关系用 . 号分开。
也可以通过手动设置。
JUL在初始化时会创建一个顶层的RootLogger作为所有Logger的父Logger。
下面的代码中就是:rootlogger->logger1->logger2logger3.
@Test
public void testLoggerParent(){
//创建一个名称为aaa的logger
Logger logger1 = Logger.getLogger("aaa");
//创建一个名称为aaa.bbb的logger
Logger logger2 = Logger.getLogger("aaa.bbb");
//创建一个名称为aaa.bbb.ccc的logger
Logger logger3 = Logger.getLogger("aaa.bbb.ccc");
//此时logger3的父Logger是logger2, logger2的父logger是logger1
//判断logger3的父Logger是不是logger2
System.out.println(logger3.getParent() == logger2);
//判断logger2的父logger是不是logger1
System.out.println(logger2.getParent() == logger1);
//logger1的父节点是顶级Logger RootLogger
System.out.println("logger1的父logger是 " + logger1.getParent());
//RootLogger的父Logger
System.out.println("RootLogger的父Logger是 " + logger1.getParent().getParent());
//手动设置父Logger
logger3.setParent(logger1);
//判断设置是否成功
System.out.println(logger3.getParent() == logger1);
}
子Logger默认会使用父Logger的Handler对象
如果使用addHandler添加新的handler,也会使用新添加的handler再输出一次
@Test
public void testUserParentHandler() {
//创建一个名为aaa的logger
Logger logger1 = Logger.getLogger("aaa");
//创建一个名为aaa.bbb的logger,父Logger是handler
Logger logger2 = Logger.getLogger("aaa.bbb");
//创建一个handler
ConsoleHandler consoleHandler = new ConsoleHandler();
//把handler添加到logger1和logger2中。
logger1.addHandler(consoleHandler);
logger2.addHandler(consoleHandler);
//使用logger进行日志输出
//记录severe级别信息
logger2.severe("severe信息");
//记录warning级别信息
logger2.warning("warning信息");
logger2.info("info信息");
logger2.config("config信息");
logger2.fine("fine信息");
logger2.finer("finer信息");
logger2.finest("finest信息");
}
分析:
每个级别的日志信息输出了三次,因为logger2使用了父Logger logger1 ,父Logger的父Logger RootLogger、还有自身的handler共三个handler,所以日志会输出三倍。
使用logger2.setUseParentHandlers(false); 设置不使用父Logger的Handler。
FileHandler和SimpleFormatter
前面说到了通过设置handler可以将日志输出到文件,这里就测试一下
@Test
public void testFileHandler(){
Logger logger = Logger.getLogger("juldemo.JULDemo");
logger.setLevel(Level.ALL);
try {
//创建一个输出到文件的handler,第一个参数是生成文件名的pattern,第二个参数是是否已追加的方式输出到文件,默认false
FileHandler fileHandler = new FileHandler("D:\\project\\idea\\log_learning\\jul_demo\\logs\\java%u.log",true);
//创建一个SimpleFormatter,输出格式
SimpleFormatter formatter = new SimpleFormatter();
//设置formatter
fileHandler.setFormatter(formatter);
//设置日志级别
fileHandler.setLevel(Level.ALL);
//把handler添加到logger
logger.addHandler(fileHandler);
//设置不使用父Logger的handler
logger.setUseParentHandlers(false);
logger.severe("severe信息");
//记录warning级别信息
logger.warning("warning信息");
logger.info("info信息");
logger.config("config信息");
logger.fine("fine信息");
logger.finer("finer信息");
logger.finest("finest信息");
} catch (IOException e) {
e.printStackTrace();
}
}
通过配置文件配置
#配置RootLogger的Handler,有java.util.logging.ConsoleHandler,java.util.logging.FileHandler
handlers= java.util.logging.ConsoleHandler,java.util.logging.FileHandler
#配置RootLogger的日志级别ALL
.level= ALL
java.util.logging.FileHandler.pattern = D:\\project\\idea\\log_learning\\jul_demo\\logs\\java%u.log
#默认一个文件最多50000条日志记录
java.util.logging.FileHandler.limit = 50000
#设置FileHandle的日志级别为ALL
java.util.logging.FileHandler.level= ALL
#配置生成一个文件
java.util.logging.FileHandler.count = 1
#配置使用SimpleFormatter格式器
java.util.logging.FileHandler.formatter = java.util.logging.SimpleFormatter
#配置追加模式
java.util.logging.FileHandler.append=true
#ConsoleHandler的日志级别默认是INFO
java.util.logging.ConsoleHandler.level = ALL
#ConsoleHandler的默认格式化器时SimpleFormatter
java.util.logging.ConsoleHandler.formatter = java.util.logging.SimpleFormatter
#设置日志格式
java.util.logging.SimpleFormatter.format= %1$tc %2$s%n%4$s: %5$s%6$s%n
@Test
public void testCustomConfig(){
LogManager logManager = LogManager.getLogManager();
try {
logManager.readConfiguration(this.getClass().getClassLoader().getResourceAsStream("logging.properties"));
Logger logger = Logger.getLogger("juldemo.JULDemo");
logger.severe("severe信息");
//记录warning级别信息
logger.warning("warning信息");
logger.info("info信息");
logger.config("config信息");
logger.fine("fine信息");
logger.finer("finer信息");
logger.finest("finest信息");
} catch (IOException e) {
e.printStackTrace();
}
}