Java学习蹊径:JUL日记体系(一)日记框架先容

[复制链接]
发表于 2026-1-1 14:56:54 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?立即注册

×
目次
打印日记
日记的级别
打印文件
日记过滤器
日记输出流程




起首,为什么要利用日记体系?

假如单纯地用System.out.println打印信息,假如项目比力大,存在大量的信息就会显得非常缭乱。
而且,当我们渴望在debug的时间打印某些信息,而运行的时间不打印,利用直接输出的方法就行不通了。
因此,我们必要利用日记框架来规范日记的输出。



打印日记





JDK为我们提供了一个自带的日记框架,位于java.util.logging(JUL名称的泉源)包下,可以利用此框架来实现日记的规范化打印:

  1. public static void main(String[] args) {
  2. //获取日志日志打印器
  3.     Logger logger = Logger.getLogger(Main.class.getName());
  4. //输出一个字符串信息
  5.     logger.info("我是日志日志");
  6. }
复制代码

以上日记打印的结果为:
   十一月 01, 2024 9:21:52 下战书 com.test.Main main
信息: 我是日记
  
可以看到,日记打印是会比寻常的print方法多出一些内容的




日记的级别





日记分为7个级别:


  • SERVER(最高级别) :一样寻常用于代表严肃错误
  • WARNING:一样寻常用于体现某些告诫,单不敷以判定为错误
  • INFO(默认级别):通例消息
  • CONFIG
  • FINE
  • FINER
  • FINEST(最低级别)

我们之前利用的代码:
  1. logger.info("我是日志日志");
复制代码

就是输出的INFO级别的日记
可以通过log方法来设定日记输出的级别:

  1.     public static void main(String[] args) {
  2.         Logger logger = Logger.getLogger(Main.class.getName());
  3. //server级别的错误可以传入异常
  4.         logger.log(Level.SEVERE,"我是server日志",new IOException("IO错误"));
  5.         logger.log(Level.WARNING,"我是warning日志");
  6.         logger.log(Level.INFO,"我是info日志");
  7.         logger.log(Level.CONFIG,"我是config日志");
  8.         logger.log(Level.FINE,"我是fine日志");
  9.     }
复制代码

输出的结果为:
   十一月 01, 2024 10:07:41 下战书 com.test.Main main
严肃: 我是server日记
java.io.IOException: IO错误
    at com.test.Main.main(Main.java:13)
  十一月 01, 2024 10:07:41 下战书 com.test.Main main
告诫: 我是warning日记
十一月 01, 2024 10:07:41 下战书 com.test.Main main
信息: 我是info日记
  
可以看到,server级别的错误可以传入非常范例,打印出的日记会明确得到非常的范例,但步调并不会由于这个传入的非常停止

别的,可以发现低于默认级别的日记没有输出,这是由于日记设定的输出品级就是输出默认级别以上的内容,而我们可以手动修改日记的打印级别:

  1. public static void main(String[] args) {
  2.         Logger logger = Logger.getLogger(Main.class.getName());
  3.         //修改日志级别
  4.         logger.setLevel(Level.ALL);
  5.         //不使用父日志处理器
  6.         logger.setUseParentHandlers(false);
  7.         //自定义日志处理器
  8.         ConsoleHandler hander = new ConsoleHandler();
  9.         hander.setLevel(Level.ALL);
  10.         logger.addHandler(hander);
  11.         logger.log(Level.SEVERE,"我是server日志",new IOException("IO错误"));
  12.         logger.log(Level.WARNING,"我是warning日志");
  13.         logger.log(Level.INFO,"我是info日志");
  14.         logger.log(Level.CONFIG,"我是config日志");
  15.         logger.log(Level.FINE,"我是fine日志");
  16.     }
复制代码

每一个Logger都有一个父日记打印器,而这个父日记打印器默认利用的ConsoleHandler,这个的日记级别为INFO。而且,默认情况下,Java 的日记记载器会利用父处理处罚器举行日记输出。因此想自界说日记输出级别时,必要先关闭父处理处罚器。

既然关闭了父处理处罚器,就必要本身再新建一个处理处罚器,在这段代码中,设置了两次Level.ALL,logger.setLevel(Level.ALL)的作用是确保日记记载器捕获全部日记信息,hander.setLevel(Level.ALL)的作用是控制现实输出的日记内容。即便记载器捕获了全部级别的日记,但只有满足处理处罚器级别条件的日记才会被真正输出。




打印文件





日记处理处罚器不但仅只有控制台打印,也可以打印文件
这时就必要利用文件处理处罚器
(文件处理处罚器和日记处理处罚器可以同时存在)

  1.         //打印到本地文件
  2.         //自定义文件处理器
  3.         FileHandler fileHandler = new FileHandler("test.log");
  4.         //设置文件打印的级别
  5.         fileHandler.setLevel(Level.WARNING);
  6.         logger.addHandler(fileHandler);
复制代码

运行后会天生一个test.log文件,文件中记载了打印的日记:

  1. <?xml version="1.0" encoding="UTF-8" standalone="no"?>
  2. <!DOCTYPE log SYSTEM "logger.dtd">
  3. <log>
  4. <record>
  5.   <date>2024-11-01T22:33:44</date>
  6.   <millis>1730471624479</millis>
  7.   <sequence>0</sequence>
  8.   <logger>com.test.Main</logger>
  9.   <level>SEVERE</level>
  10.   <class>com.test.Main</class>
  11.   <method>main</method>
  12.   <thread>1</thread>
  13.   <message>我是server日志</message>
  14.   <exception>
  15.     <message>java.io.IOException: IO错误</message>
  16.     <frame>
  17.       <class>com.test.Main</class>
  18.       <method>main</method>
  19.       <line>32</line>
  20.     </frame>
  21.   </exception>
  22. </record>
  23. <record>
  24.   <date>2024-11-01T22:33:44</date>
  25.   <millis>1730471624496</millis>
  26.   <sequence>1</sequence>
  27.   <logger>com.test.Main</logger>
  28.   <level>WARNING</level>
  29.   <class>com.test.Main</class>
  30.   <method>main</method>
  31.   <thread>1</thread>
  32.   <message>我是warning日志</message>
  33. </record>
  34. </log>
复制代码

可以看到,文件处理处罚器打印出的内容格式和控制台处理处罚器打印出的内容格式不太一样,文件处理处罚器默认打印出的格式为xml格式

如许有点难以阅读,我们想修改一下文件处理处罚器打印出的格式,应该怎么办呢?

这时就要用到别的一个类,叫做SimpleFormatter,这个类叫做日记格式化器,是专门用于将日记转化为简单易读的格式的。
而控制台处理处罚器就默认利用了这个类。

在文件处理处罚器中利用.setFormatter()方法添加格式化器:

  1.         SimpleFormatter simpleFormatter = new SimpleFormatter();
  2.         //打印到本地文件
  3.         //自定义文件处理器
  4.         FileHandler fileHandler = new FileHandler("test.log");
  5.         fileHandler.setFormatter(simpleFormatter);
  6.         //设置文件打印的级别
  7.         fileHandler.setLevel(Level.WARNING);
  8.         logger.addHandler(fileHandler);
复制代码

除了SimpleFormatter,也可以利用XMLFormatter来将日记的格式改为xml格式




日记过滤器





假如我们不渴望某些日记信息被输出,可以自界说日记过滤器


  1. Filter customFilter = new Filter() {
  2.             @Override
  3.             public boolean isLoggable(LogRecord record) {
  4.                 // 只记录包含 "IMPORTANT" 的日志
  5.                 return record.getMessage().contains("IMPORTANT");
  6.             }
  7.         };
  8. // 将过滤器添加到处理器
  9. handler.setFilter(customFilter);
复制代码

自界说日记过滤器的本质是通过重写Filter接口中的isLoggable接口实现的

过滤器可以被应用到handler中,也可以被应用到logger中

  1. logger.setFilter(customFilter);
复制代码




日记输出流程







整个日记输出流程是一个层层筛选、徐徐处理处罚的过程:


  • 应用步调天生日记,Logger 汲取并通过其自身的过滤器举行开端筛选。
  • 筛选通过的日记记载通报给 Handler,并颠末 Handler 的过滤器进一步筛选。
  • 终极符合条件的日记通过 Handler 输出到指定的外部体系。
回复

使用道具 举报

登录后关闭弹窗

登录参与点评抽奖  加入IT实名职场社区
去登录
快速回复 返回顶部 返回列表