1、JUL简介
- JUL全程 Java Util Logging,它是java原生的日志框架,使用时不需要另外引用第三方的类库
- 相对其他的框架使用方便,学习简单,主要是使用在小型应用中。
2、JUL组件介绍
- Logger:被称为记录器,应用程序通过获取Logger对象,抵用其API来发布日志信息。Logger通常被认为是访问日志系统的入口程序。
- Handler:处理器,每个Logger都会关联一个或者是一组Handler,Logger会将日志交给关联的Handler去做处理,由Handler负责将日志做记录。Handler具体实现了日志的输出位置,比如可以输出到控制台或者是文件中等等。
- Filter:过滤器,根据需要定制哪些信息会被记录,哪些信息会被略过。
- Formatter:格式化组件,它负责对日志中的数据和信息进行转换和格式化,所以它决定了我们输出日志最终的形式。
- Level:日志的输出级别,每条日志消息都有一个关联的级别。我们根据输出级别的设置,用来展现最终所呈现的日志信息。根据不同的需求,去设置不同的级别。
3、Logger入门使用
导包
import java.util.logging.Logger;
@Test
public void test01(){
//Logger对象的创建方式,不能直接new对象
//取得对象的方法参数,需要引入当前类的全路径字符串
Logger logger = Logger.getLogger("com.xc.mylog.JULTest");
//第一种方式: 直接调用日志级别相关的方法,方法中传递日志输出信息
logger.info("输出info信息1");
//第二种方式:调用通用的log方法,然后在里面通过Level类型来定义日志的级别参数,
// 以及搭配日志输出信息的参数
logger.log(Level.INFO,"输出info信息2");
//日志添加参数
String name = "zs";
int age = 23;
logger.log(Level.INFO,"学生的姓名:{0},年龄:{1}",new Object[]{name,age});
}
输出结果:
六月 20, 2022 9:23:41 下午 com.xc.mylog.JULTest test01
信息: 输出info信息1
六月 20, 2022 9:23:41 下午 com.xc.mylog.JULTest test01
信息: 输出info信息2
六月 20, 2022 9:23:41 下午 com.xc.mylog.JULTest test01
信息: 学生的姓名:zs,年龄:23
Process finished with exit code 0
4、Logger日志级别
日志级别源码类:java.util.logging.Level
- 日志普通级别
//错误 --- 最高级的日志级别
public static final Level SEVERE = new Level("SEVERE",1000, defaultBundle);
//WARNING : 警告
public static final Level WARNING = new Level("WARNING", 900, defaultBundle);
//INFO : (默认级别)消息
public static final Level INFO = new Level("INFO", 800, defaultBundle);
//CONFIG : 配置
public static final Level CONFIG = new Level("CONFIG", 700, defaultBundle);
//FINE : 详细信息
public static final Level FINE = new Level("FINE", 500, defaultBundle);
//FINER : 较详细信息
public static final Level FINER = new Level("FINER", 400, defaultBundle);
//FINEST : 非常详细信息 --- 最低级的日志级别
public static final Level FINEST = new Level("FINEST", 300, defaultBundle);
- 两个特殊级别
//OFF 可用来关闭日志记录
public static final Level OFF = new Level("OFF",Integer.MAX_VALUE, defaultBundle);
//ALL 启用所有消息的日志记录
public static final Level ALL = new Level("ALL", Integer.MIN_VALUE, defaultBundle);
原理分析
- 根据new Level第二个数值参数判断,如设置info级别,对应数值就是800
- 那么>=800的SEVERE 、WARNING、INFO三个级别的都可以输出
- 同理off大于Integer.MAX_VALUE没日志,大于Integer.MIN_VALUE输出所有日志
@Test
public void test02(){
Logger logger = Logger.getLogger("com.xc.mylog.JULTest");
//打印日志
logger.severe("severe信息");
logger.warning("warning信息");
logger.info("info信息");
logger.config("config信息");
logger.fine("fine信息");
logger.finer("finer信息");
logger.finest("finest信息");
}
输出结果:
六月 20, 2022 9:39:49 下午 com.xc.mylog.JULTest test02
严重: severe信息
六月 20, 2022 9:39:49 下午 com.xc.mylog.JULTest test02
警告: warning信息
六月 20, 2022 9:39:49 下午 com.xc.mylog.JULTest test02
信息: info信息
Process finished with exit code 0
由输出结果可知,默认的输出级别为info
自定义日志的级别
- 关闭按照父logger默认的方式去进行操作
- 日志记录器和处理器的级别进行统一的设置,才会达到日志显示相应级别的效果
@Test
public void test03(){
//日志记录器
Logger logger = Logger.getLogger("com.xc.mylog.JULTest");
//将默认的日志打印方式关闭掉
//参数设置为false,我们打印日志的方式就不会按照父logger默认的方式去进行操作
logger.setUseParentHandlers(false);
//处理器Handler
//在此我们使用的是控制台日志处理器,取得处理器对象
ConsoleHandler handler = new ConsoleHandler();
//创建日志格式化组件对象
SimpleFormatter formatter = new SimpleFormatter();
//在处理器中设置输出格式
handler.setFormatter(formatter);
//在记录器中添加处理器
logger.addHandler(handler);
//设置日志的打印级别
//此处必须将日志记录器和处理器的级别进行统一的设置,才会达到日志显示相应级别的效果
//logger.setLevel(Level.CONFIG);
//handler.setLevel(Level.CONFIG);
logger.setLevel(Level.ALL);
handler.setLevel(Level.ALL);
logger.severe("severe信息");
logger.warning("warning信息");
logger.info("info信息");
logger.config("config信息");
logger.fine("fine信息");
logger.finer("finer信息");
logger.finest("finest信息");
}
输出结果:
六月 20, 2022 9:47:02 下午 com.xc.mylog.JULTest test03
严重: severe信息
六月 20, 2022 9:47:02 下午 com.xc.mylog.JULTest test03
警告: warning信息
六月 20, 2022 9:47:02 下午 com.xc.mylog.JULTest test03
信息: info信息
六月 20, 2022 9:47:02 下午 com.xc.mylog.JULTest test03
配置: config信息
六月 20, 2022 9:47:02 下午 com.xc.mylog.JULTest test03
详细: fine信息
六月 20, 2022 9:47:02 下午 com.xc.mylog.JULTest test03
较详细: finer信息
六月 20, 2022 9:47:02 下午 com.xc.mylog.JULTest test03
非常详细: finest信息
Process finished with exit code 0
日志持久化(保存到磁盘)
- 用户使用Logger来进行日志的记录,Logger可以持有多个处理器Handler
- 日志的记录使用的是Logger,日志的输出使用的是Handler
- 可以输出到控制台也可以输出到文件,也可以两者兼备
@Test
public void test04() throws IOException {
Logger logger = Logger.getLogger("com.xc.mylog.JULTest");
logger.setUseParentHandlers(false);
//文件日志处理器
FileHandler handler = new FileHandler("D:\\test\\myLogTest.log");
SimpleFormatter formatter = new SimpleFormatter();
handler.setFormatter(formatter);
logger.addHandler(handler);
//也可以同时在控制台和文件中进行打印
ConsoleHandler handler2 = new ConsoleHandler();
handler2.setFormatter(formatter);
logger.addHandler(handler2); //可以在记录器中同时添加多个处理器
logger.setLevel(Level.ALL);
//输出到文件的级别为all
handler.setLevel(Level.ALL);
//输出到控制台的解绑为config
handler2.setLevel(Level.CONFIG);
logger.severe("severe信息");
logger.warning("warning信息");
logger.info("info信息");
logger.config("config信息");
logger.fine("fine信息");
logger.finer("finer信息");
logger.finest("finest信息");
}
4、Logger之间的父子关系
- JUL中Logger之间是存在”父子”关系的,这种父子关系不是我们普遍认为的类之间的继承关系
- 关系是通过树状结构存储的
- JUL在初始化时会创建一个顶层RootLogger作为所有Logger的父Logger
- RootLogger对象作为树状结构的根节点存在的
- 将来自定义的父子关系通过路径来进行关联
- 父子关系,同时也是节点之间的挂载关系
@Test
public void test05(){
/*
从下面创建的两个logger对象看来
我们可以认为logger1是logger2的父亲
*/
//父亲是RootLogger,名称默认是一个空的字符串
//RootLogger可以被称之为所有logger对象的顶层logger
Logger logger1 = Logger.getLogger("com.xc");
Logger logger2 = Logger.getLogger("com.xc.mylog");
Logger logger3 = Logger.getLogger("com.xc.mylog.JULTest");
System.out.println("logger1的父Logger引用为:"
+logger1.getParent()+"; 名称为"+logger1.getName()+";" +
" 父亲的名称为"+logger1.getParent().getName());
System.out.println("logger2的父Logger引用为:"
+logger2.getParent()+"; 名称为"+logger2.getName()+";" +
" 父亲的名称为"+logger2.getParent().getName());
System.out.println("logger3的父Logger引用为:"
+logger3.getParent()+"; 名称为"+logger3.getName()+";" +
" 父亲的名称为"+logger3.getParent().getName());
}
输出结果:
logger1的父Logger引用为:java.util.logging.LogManager$RootLogger@71bc1ae4; 名称为com.xc; 父亲的名称为
logger2的父Logger引用为:java.util.logging.Logger@6ed3ef1; 名称为com.xc.mylog; 父亲的名称为com.xc
logger3的父Logger引用为:java.util.logging.Logger@2437c6dc; 名称为com.xc.mylog.JULTest; 父亲的名称为com.xc.mylog
- 父亲所做的设置,也能够同时作用于儿子
@Test
public void test06(){
Logger logger1 = Logger.getLogger("com.xc.mylog");
Logger logger2 = Logger.getLogger("com.xc.mylog.JULTest");
//父亲设置级别为all
logger1.setUseParentHandlers(false);
ConsoleHandler handler = new ConsoleHandler();
SimpleFormatter formatter = new SimpleFormatter();
handler.setFormatter(formatter);
logger1.addHandler(handler);
handler.setLevel(Level.ALL);
logger1.setLevel(Level.ALL);
//儿子默认级别为info
logger2.severe("severe信息");
logger2.warning("warning信息");
logger2.info("info信息");
logger2.config("config信息");
logger2.fine("fine信息");
logger2.finer("finer信息");
logger2.finest("finest信息");
}
输出结果:
六月 20, 2022 10:08:47 下午 com.xc.mylog.JULTest test05
严重: severe信息
六月 20, 2022 10:08:47 下午 com.xc.mylog.JULTest test05
警告: warning信息
六月 20, 2022 10:08:47 下午 com.xc.mylog.JULTest test05
信息: info信息
六月 20, 2022 10:08:47 下午 com.xc.mylog.JULTest test05
配置: config信息
六月 20, 2022 10:08:47 下午 com.xc.mylog.JULTest test05
详细: fine信息
六月 20, 2022 10:08:47 下午 com.xc.mylog.JULTest test05
较详细: finer信息
六月 20, 2022 10:08:47 下午 com.xc.mylog.JULTest test05
非常详细: finest信息
Process finished with exit code 0
5、Logger配置文件原理
Logger默认读取配置文件源码
String fname = System.getProperty("java.util.logging.config.file");
if (fname == null) {
fname = System.getProperty("java.home");
if (fname == null) {
throw new Error("Can't find java.home ??");
}
File f = new File(fname, "lib");
f = new File(f, "logging.properties");
fname = f.getCanonicalPath();
}
try (final InputStream in = new FileInputStream(fname)) {
final BufferedInputStream bin = new BufferedInputStream(in);
readConfiguration(bin);
}
默认会从java.home(jdk的jre文件夹)下的lib文件下的默认生成loggin.properties,如下
- 自定义修改为只输出到日志文件中
- 自定义日志是否追加,默认覆盖
@Test
public void test07() throws Exception {
Logger logger = Logger.getLogger("com.xc.mylog.JULTest");
logger.severe("severe信息");
logger.warning("warning信息");
logger.info("info信息");
logger.config("config信息");
logger.fine("fine信息");
logger.finer("finer信息");
logger.finest("finest信息");
}
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/148614.html