定义:

JUL全称Java util logging,是java原生的日志框架,使用时不需要另外引入第三方类库,相对于其他框架使用方便,学习简单,能够在小型的应用中灵活使用。

架构:

  • Application:我们的程序应用。
  • LogManager:管理Logger,是个单例Bean。
  • Logger:日志记录器,我们的应用程序通过获取日志记录器Logger对象,调用其API来发布日志信息,Logger通常是应用程序访问日志系统的入口。
  • Handler:日志处理器,每个Logger会关联持有多个Handler,Logger会把日志交给Handler进行处理,由Handler负责日志记录。Handler在这里是一个抽象,其具体实现决定了日志输出的位置,比如控制台,文件等。
  • Formattter:日志格式转化器,负责对日志的格式进行处理。决定了输出的日志的最终形式。
  • Level:每条日志信息都有一个关联的日志级别,该级别处理指导了日志信息的重要性。我们可以将Level作用于Logger和Handler上。以便于我们过滤消息。
  • Filter:过滤器,根据规则过滤掉某些日志信息。

总体流程:

  1. 初始化LogManager,加载logging.properties配置文件,添加Logger到LogManager中。
  2. 从单例Bean LogManager获取Logger。
  3. 设置日志级别Level。
  4. Handler处理日志输出。
  5. Formatter处理日志格式。

日志的级别:

JUL日志级别由类java.util.logging.Level记录,总共有七个日志级别,由高到低分别是:

SEVERE //错误信息,一般是记录导致系统终止的信息。
WARNING //警告信息,一般记录程序的问题,该问题不会导致系统终止,但是却值得我们关注。
INFO // 一般信息,一般记录一些连接信息,访问信息等。(这是JUL的默认级别)
CONFIG // 一般记录加载配置文件等日志信息。
FINE // Debug日志信息,一般记录程序一般运行的状态。执行的流程参数的传递等信息。
FINER //与FINE 类似,只是记录的颗粒度要高一些。
FINEST //与上面两个类似,只是记录的颗粒度要高一些。

还有两个特殊的级别:
OFF: 可用来关闭日志信息,不输出任何级别的日志。
ALL: 记录所有级别的日志信息。

当Logger或者Handler设置了某一日志级别,低于该级别的日志信息将不会被记录。

入门案例:

public class JULDemo {@Testpublic void testHelloWorld(){//创建日志记录器,传入参数是日志记录器的名称Logger logger = Logger.getLogger("juldemo.JULDemo");//记录severe级别信息logger.severe("severe信息");//记录warning级别信息logger.warning("warning信息");logger.info("info信息");logger.config("config信息");logger.fine("fine信息");logger.finer("finer信息");logger.finest("finest信息");}
}

输出结果:

因为默认的日志级别是INFO,所以比INFO级别低的 CONFIG、FINE、FINER、FINEST的日志记录消息没有记录。

自定义日志级别:

@Testpublic void testCustomLogLevel(){//创建日志记录器,传入参数是日志记录器的名称Logger logger = Logger.getLogger("juldemo.JULDemo");//创建一个输出到控制台的handlerConsoleHandler consoleHandler = new ConsoleHandler();//设置handler的日志级别为ALL,输出全部日志。consoleHandler.setLevel(Level.ALL);//把handler添加到logger中logger.addHandler(consoleHandler);//logger也设置日志级别为ALLlogger.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信息");}

结果:

七个级别的日志信息都输出了。

Logger之间的父子关系:

JUL的Logger之间会存在父子关系,这种父子关系通过树状关系存储。JUL在初始化时会创建一个顶层的RootLogger作为所有Logger的父Logger。RootLogger作为树结构的根节点,Logger之间的关系通过树路径来关联。Logger记录器是用名称作为标志的。子Logger和默认使用父Logger的Handler。

Logger的父子关系默认是通过名子的层级关系来确定的。层级关系用 . 号分开。
也可以通过手动设置父Logger。

@Testpublic void testLoggerParent(){//创建一个名称为aaa的loggerLogger logger1 = Logger.getLogger("aaa");//创建一个名称为aaa.bbb的loggerLogger logger2 = Logger.getLogger("aaa.bbb");//创建一个名称为aaa.bbb.ccc的loggerLogger logger3 = Logger.getLogger("aaa.bbb.ccc");//此时logger3的父Logger是logger2, logger2的父logger是logger1//判断logger3的父Logger是不是logger2System.out.println(logger3.getParent() == logger2);//判断logger2的父logger是不是logger1System.out.println(logger2.getParent() == logger1);//logger1的父节点是顶级Logger RootLoggerSystem.out.println("logger1的父logger是 " + logger1.getParent());//RootLogger的父LoggerSystem.out.println("RootLogger的父Logger是 " + logger1.getParent().getParent());//手动设置父Loggerlogger3.setParent(logger1);//判断设置是否成功System.out.println(logger3.getParent() == logger1);}

执行结果:

子Logger默认会使用父Logger的Handler:

@Testpublic void testUserParentHandler() throws IOException {//创建一个名为aaa的loggerLogger logger1 = Logger.getLogger("aaa");//创建一个名为aaa.bbb的logger,父Logger是handlerLogger logger2 = Logger.getLogger("aaa.bbb");//创建一个handlerConsoleHandler 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。

结果:

只用了自身的handler。

使用FileHandler和SimpleFormatter

 @Testpublic void testFileHandler(){Logger logger = Logger.getLogger("juldemo.JULDemo");logger.setLevel(Level.ALL);try {//创建一个输出到文件的handler,第一个参数是生成文件名的pattern,第二个参数是是否已追加的方式输出到文件,默认falseFileHandler fileHandler = new FileHandler("D:\\logs\\java%u.log",true);//创建一个SimpleFormatter,输出格式SimpleFormatter formatter = new SimpleFormatter();//设置formatterfileHandler.setFormatter(formatter);//设置日志级别fileHandler.setLevel(Level.ALL);//把handler添加到loggerlogger.addHandler(fileHandler);//设置不使用父Logger的handlerlogger.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();}}

输出到文件:

配置文件详解:

上面的使用方式都是使用硬编码方式进行配置,现在介绍配置文件配置。

默认的配置文件:
$JAVA_HOME/jre/lib/logging.properties
默认配置:

#配置RootLogger的Handler,多个用逗号分隔。默认只有一个输出到控制台的handler
handlers= java.util.logging.ConsoleHandler#配置RootLogger的日志级别,默认是INFO
.level= INFO#配置FileHandler
#配置FileHandler的生成文件路径以及文件名的生成方式
java.util.logging.FileHandler.pattern = %h/java%u.log
#默认一个文件最多50000条日志记录
java.util.logging.FileHandler.limit = 50000
#默认生成一个文件
java.util.logging.FileHandler.count = 1
#默认使用XMLFormatter格式器
java.util.logging.FileHandler.formatter = java.util.logging.XMLFormatter#ConsoleHandler的日志级别默认是INFO
java.util.logging.ConsoleHandler.level = INFO
#ConsoleHandler的默认格式化器时SimpleFormatter
java.util.logging.ConsoleHandler.formatter = java.util.logging.SimpleFormatter

我们可以使用自定义的文件或者修改默认配置文件进行配置。


#配置RootLogger的Handler,有java.util.logging.ConsoleHandler,java.util.logging.FileHandler
handlers= java.util.logging.ConsoleHandler,java.util.logging.FileHandler#配置RootLogger的日志级别ALL
.level= ALLjava.util.logging.FileHandler.pattern = D:/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

使用:

 @Testpublic 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();}}

结果:

并且生成了日志文件,这里就不贴了。

如果不想用logmanager加载指定配置文件的话,就直接修改$JAVA_HOME/jre/lib/logging.properties文件也行。

Java日志框架之JUL(java util logging)详解相关推荐

  1. Java日志框架学习--JUL和Log4j--上

    Java日志框架学习--JUL和Log4j--上 引言 日志框架 市面流行的日志框架 日志门面和日志框架的区别 JUL JUL简介 JUL组件介绍 实际使用 Logger之间的父子关系 默认配置文件位 ...

  2. java日志框架(一)JUL 学习 ,这个是什么,他在代码中如何使用,一篇文章讲清楚

    这里写目录标题 JUL 是什么 JUL组件介绍 代码中如何使用(控制台输出) 日志级别 自定义输出级别 输出日志到文件(磁盘文件中) 日志对象父子关系 配置文件 使用方法总结 JUL 是什么 JUL全 ...

  3. Java自动化测试框架-12 - TestNG之xml文件详解篇 (详细教程)

    1.简介 现在这篇,我们来学习TestNG.xml文件,前面我们已经知道,TestNG就是运行这个文件来执行测试用例的.通过本篇,你可以进一步了解到:这个文件是配置测试用例,测试套件.简单来说,利用这 ...

  4. Java日志框架学习笔记

    Java日志框架学习笔记 文章目录 0 主流Java日志框架 1 log4j 1.1 理论知识 1.1.1 Loggers日志记录器 1.1.2 Appenders输出端 1.1.3 Layout日志 ...

  5. 学习Java日志框架之——搞懂JUL(java.util.logging)

    文章目录 系列文章目录 一.JUL简介 二.JUL组件介绍 三.代码实例 1.入门案例 2.日志级别 (1)默认日志级别源码分析 3.自定义日志级别 4.将日志输出到文件中 5.Logger的父子关系 ...

  6. java日志框架JUL、JCL、Slf4j、Log4j、Log4j2、Logback 一网打尽

    为什么程序需要记录日志 我们不可能实时的24小时对系统进行人工监控,那么如果程序出现异常错误时要如何排查呢?并且系统在运行时做了哪些事情我们又从何得知呢?这个时候日志这个概念就出现了,日志的出现对系统 ...

  7. Java日志框架 -- 日志框架介绍、日志门面技术、JUL日志(JUL架构、JUL入门示例、JUL日志级别、JUL日志的配置文件)

    1. 日志的概念 日志文件是用于记录系统操作事件的文件集合,可分为事件日志和消息日志.具有处理历史数据.诊断问题的追踪以及理解系统的活动等重要作用. 2. Java日志框架 问题: 控制日志输出的内容 ...

  8. Java 日志框架 JUL

    文章目录 日志文件的重要性 常见日志框架 什么是JUL JUL架构介绍 入门案例 JUL日志级别 Logger之间的父子关系 日志的配置文件 日志原理解析 日志文件的重要性 做开发最怕的就是线上系统出 ...

  9. 可能是全网最全,JAVA日志框架适配、冲突解决方案,可以早点下班了!

    点击上方"Java基基",选择"设为星标" 做积极的人,而不是积极废人! 每天 14:00 更新文章,每天掉亿点点头发... 源码精品专栏 原创 | Java ...

最新文章

  1. python find(urlopen.read())_Python小白必看之urlopen()详解
  2. CSS中position详解与常见应用实现
  3. STM32开发板入门教程(十三) - SPI模式读写SD卡
  4. 《JavaWeb从入门到改行》注册时向指定邮箱发送邮件激活
  5. 了解招聘中的这些潜台词,找工作少走弯路
  6. 局域网Ubuntu与WinXP实现文件共享
  7. HTML网站右键禁用F12代码 屏蔽审查元素 防止修改页面代码
  8. 微信生态圈盈­利模式分析
  9. 机器学习中二分类逻辑回归的学习笔记
  10. 阿里云专家带你揭秘云计算数据底座——对象存储
  11. Rust : stevenbai.top学习站点
  12. 中国移动 · 边缘计算技术白皮书 | PDF下载
  13. mysql 获取百分比函数,并对结果保留2位小数。
  14. 分位数回归--基于R
  15. 格式工厂 wav 比特率_鸡娃常用工具系列一格式工厂(音频转换软件)
  16. 开源软件、自由软件、Copyleft、CC都是啥,傻傻分不清楚?
  17. 用python实现监听微信撤回消息
  18. 新手入门,想用VB给班上写一个自动播放上下课铃声的程序,求教
  19. 一个程序员的自白:我为什么写博客
  20. CF1005A Tanya and Stairways

热门文章

  1. Spring框架学习笔记05:Spring AOP基础
  2. 数据库笔记08:实现索引
  3. 【NOI2016】网格,离散化+求割点
  4. 中职计算机应用基础微课获奖视频,浅谈微课在中职计算机应用基础教学中的应用...
  5. linux配置iscsi无账号密码,linux配置ISCSI服务器的方法
  6. 【英语学习】【医学】无机化学 - 化合物命名(1) - 离子化合物
  7. python中template是什么意思啊_Python中Template使用的一个小技巧
  8. c#ref和out的相同点_C#中使用ref和out一点认识!
  9. cve-2020-0796_CVE20200796 | Windows SMBv3客户端/永痕之黑漏洞复现
  10. CCS 3.3中统计程序运行的时间