JUL日志组件
-
Logger 负责调用其有的Handler进行日志输出
-
Handler 负责具体的日志输出,有不同的实现类,比如(ConsoleHandler,控制台输出,FileHandler 文件输出)
-
LogRecord 一条具体的日志对象,比如这条日志所在线程、日志级别,日志名称,日志内容,时间等信息。Logger对象负责创建然后调用handler,handler负责进行输出
-
Formatter Handler在输出前会调用Formatter 对LogRecord 进行格式化,如简单字符串格式化,Html格式化,XML格式化等。
-
LogManager 负责创建日志对象,并将创建的日志对象继承RootLogger的默认配置。
在任何日志框架中都会有继承性的概念,在获取Logger对象时,默认会继承RootLogger的配置,但自己的Logger也可以单独设置级别,Handler等。但是如果日志名称是包名进行命名的话,子包默认会继承父包的配置,例如 指定了com.a.b这个包的Handler是ConsoleHandler,Level是info,则com.a.b.c或者 com.a.b.c.d等属于这个包的Logger都会默认继承这个包的配置。
- 测试基本JUL使用
/**
* 测试JDK自带的日志,并使用编程式配置修改默认规则
* <p>
* 日志输出逻辑梳理:
* Formatter 将LogRecord格式化成需要的字符串如 标准字符串或者XML等
* Handler 不同的handler输出日志方式不同,每个handler都需要设置formatter,和level等
* handler对象可以将格式化好的日志内容输出到控制台或者文件
* Logger:负责调用所有的handler方法进行输出
* LogRecord : 一条具体的日志记录对象包括本条记录时间,内容,线程,级别等等
*
* @throws Exception
*/
@Test
public void test1() throws Exception {
Logger logger = Logger.getLogger("JUCLogger");
logger.setUseParentHandlers(false);
//logger本身的级别为All,真正输出时,需要看处理器的级别
SimpleFormatter simpleFormatter = new SimpleFormatter();
ConsoleHandler consoleHandler = new ConsoleHandler();
FileHandler fileHandler = new FileHandler("D:\\2022\\logs\\log.txt");
fileHandler.setLevel(Level.WARNING);
fileHandler.setFormatter(simpleFormatter);
consoleHandler.setFormatter(simpleFormatter);
consoleHandler.setLevel(Level.ALL);
logger.addHandler(consoleHandler);
logger.addHandler(fileHandler);
logger.setLevel(Level.ALL);//先判断是否符合Logger的level,再继续判断是否符合每个handler的level+
logger.severe("severe");
logger.warning("warning");
logger.info("info");
logger.fine("fine");
logger.finest("finest");
}
- 测试JUL继承
/**
* 日志的继承,在获取日志对象时,如果传递的是全限定类名,则LogManager会寻找
* 是否有当前限定类型上一级的logger,如果有则日志配置默认继承该logger
* 否则默认继承Rootlogger
*
* @throws Exception
*/
@Test
public void test2() throws Exception {
//1.创建一个父级logger
Logger plog = Logger.getLogger("com.a");
plog.setUseParentHandlers(false);
plog.setLevel(Level.WARNING);
// FileHandler fileHandler = new FileHandler("D:\\2022\\logs\\logparent.txt");
ConsoleHandler handler = new ConsoleHandler();
handler.setFormatter(new SimpleFormatter());
plog.addHandler(handler);
//2.创建一个子logger
Logger logger = Logger.getLogger("com.a.b"); //如果有父级logger,则loggerManager会让其继承父类的配置
logger.warning("warning");
logger.info("info");
logger.severe("sever");
}
可以看到确实继承了,只打印出了warn级别以上的日志。
- 使用jul配置文件方式
#指定 com.example 包下的日志配置
com.example.useParentHandlers=false
com.example.level=ALL
com.example.handlers=java.util.logging.ConsoleHandler,java.util.logging.FileHandler
#设置项目的基本jul - log
#控制台输出日志级别为fine,格式为简单格式
java.util.logging.ConsoleHandler.level = ALL
java.util.logging.ConsoleHandler.formatter = java.util.logging.SimpleFormatter
#文件输出日志格式为XML格式,级别为warning
java.util.logging.FileHandler.pattern = D:/2022/logs/java%u.log
java.util.logging.FileHandler.limit = 50000
java.util.logging.FileHandler.count = 1
java.util.logging.FileHandler.formatter = java.util.logging.XMLFormatter
java.util.logging.FileHandler.append = true
java.util.logging.FileHandler.level = WARNING
/**
* 测试自定义JUL配置文件
*
* @throws Exception
*/
@Test
public void test4() throws Exception {
InputStream resourceAsStream = this.getClass().getClassLoader().getResourceAsStream("jul.properties");
LogManager.getLogManager().readConfiguration(resourceAsStream);
//获取logger
Logger logger = Logger.getLogger(this.getClass().getName());
logger.severe("severe");
logger.warning("warning");
logger.info("info");
logger.config("config");
logger.fine("fine");
logger.finer("finer");
logger.finest("finest");
}
使用配置文件方式也是同样可以起效的。