JUL全称Java util Logging是java原生的日志框架,使用时不需要另外引用第三方类库,相对其他日志框 架使用方便,学习简单,能够在小型应用中灵活使用。
JUL在项目开发中用的比较少了,因为它的功能有点单一,无法满足项目中一些复杂的需求(比如输出的日志文件按时间存储,这个它是无法实现的),但作为学习,了解一下他是怎么实现的,也是一个不错的方式
架构介绍
- Loggers:被称为记录器,应用程序通过获取Logger对象,调用其API来来发布日志信息。Logger通常时应用程序访问日志系统的入口程序。
- Appenders:也被称为Handlers,每个Logger都会关联一组Handlers,Logger会将日志交给关联 Handlers处理,由Handlers负责将日志做记录。Handlers在此是一个抽象,其具体的实现决定了日志记录的位置可以是控制台、文件、网络上的其他日志服务或操作系统日志等。
- Layouts:也被称为Formatters,它负责对日志事件中的数据进行转换和格式化。Layouts决定了数据在一条日志记录中的最终形式。
- Level:每条日志消息都有一个关联的日志级别。该级别粗略指导了日志消息的重要性和紧迫,我可以将Level和Loggers,Appenders做关联以便于我们过滤消息。Filters:过滤器,根据需要定制哪些信息会被记录,哪些信息会被放过。
总结一下就是:
用户使用
Logger
来进行日志记录,
Logger
持有若干个
Handler
,日志的输出操作是由
Handler
完成的。在Handler在输出日志前,会经过
Filter
的过滤,判断哪些日志级别过滤放行哪些拦截
Handler
会将日志内容输出到指定位置(日志文件、控制台等)。Handler
在输出日志时会使用
Layout
,将输出内容进 行排版。
入门案例
@Test public void JULTest(){ //这个主要用于测试JUL这个springboot自带的日志框架 //1 获取日志记录器对象 Logger logger = Logger.getLogger("JULTest"); //2 日志记录输出过程 logger.info("hello,JUL"); logger.warning("程序发出警告"); //通用的方法进行日志记录 logger.log(Level.WARNING,"程序发出警告2"); // 占位符的日志输出 String name = "jack"; Integer age = 18; logger.log(Level.WARNING,"姓名:{0},年龄:{1}",new Object[]{name,age}); logger.log(Level.SEVERE,"severe"); logger.log(Level.WARNING,"waring"); logger.log(Level.INFO,"info"); logger.log(Level.CONFIG,"config"); logger.log(Level.FINE,"FINE"); logger.log(Level.FINER,"FINER"); logger.log(Level.FINEST,"FINEST"); // 最后这里输出severe,waring,info,说明JUL默认的日志级别是info }
JUL的日志级别
jul中定义的日志级别
虽然我们测试了
7
个日志级别但是默认只实现
info
以上的级别 ,简单的说就是默认的日志级别是info,低于这个日志级别的输出内容不会对其进行记录。
自定义日志级别配置
public void customLogLevel() throws IOException { // 获取logger对象 Logger logger = Logger.getLogger("customLogLevel"); // 关闭系统默认配置 logger.setUseParentHandlers(false); // 自定义日志配置级别 ConsoleHandler consoleHandler = new ConsoleHandler(); SimpleFormatter simpleFormatter = new SimpleFormatter(); // 关联 consoleHandler.setFormatter(simpleFormatter); logger.addHandler(consoleHandler); // 配置日志具体的级别 logger.setLevel(Level.INFO); consoleHandler.setLevel(Level.INFO); // 输出到文件 FileHandler fileHandler = new FileHandler("C:\\Users\\admin\\Desktop\\project\\log\\JUL.log"); // 关联 logger.addHandler(fileHandler); fileHandler.setFormatter(simpleFormatter); logger.log(Level.SEVERE,"severe"); logger.log(Level.WARNING,"waring"); logger.log(Level.INFO,"info"); logger.log(Level.CONFIG,"config"); logger.log(Level.FINE,"FINE"); logger.log(Level.FINER,"FINER"); logger.log(Level.FINEST,"FINEST11"); }
根据上面的代码,代入JUL的架构代码,我们就可以了解到JUL基于一个顶级父类去初始化,初始化的对象是logger层,logger层下面可以定义多个Handler,上面就定义了二个Handler,分别是consoleHandler和 FileHandler,一个用于在控制台输出日志,一个用于将日志写入到文件中,Handler需要配置Formatter格式化对象去格式化输出的日志,到这里整个架构就很清晰了
Logger之间的父子关系
JUL
中
Logger
之间存在父子关系,这种父子关系通过树状结构存储,
JUL
在初始化时会创建一个顶层 RootLogger作为所有
Logger
父
Logger
,存储上作为树状结构的根节点。并父子关系通过路径来关联。
@Test public void testLogParent() throws Exception { // 日志记录器对象父子关系 Logger logger1 = Logger.getLogger("com.itheima.log"); Logger logger2 = Logger.getLogger("com.itheima"); System.out.println(logger1.getParent() == logger2); // 所有日志记录器对象的顶级父元素 class为java.util.logging.LogManager$RootLoggername为"" System.out.println("logger2 parent:" + logger2.getParent() + ",name:" + logger2.getParent().getName()); // 一、自定义日志级别 // a.关闭系统默认配置 logger2.setUseParentHandlers(false); // b.创建handler对象 ConsoleHandler consoleHandler = new ConsoleHandler(); // c.创建formatter对象 SimpleFormatter simpleFormatter = new SimpleFormatter(); // d.进行关联 consoleHandler.setFormatter(simpleFormatter); logger2.addHandler(consoleHandler); // e.设置日志级别 logger2.setLevel(Level.ALL); consoleHandler.setLevel(Level.ALL); // 测试日志记录器对象父子关系 logger1.severe("severe"); logger1.warning("warning"); logger1.info("info"); logger1.config("config"); logger1.fine("fine"); logger1.finer("finer"); logger1.finest("finest"); }
Logger类的顶级父类是RootLogger,名字是"";Logger类是通过名字进行分层的,
Logger logger1 = Logger.getLogger("com.itheima.log");
Logger logger2 = Logger.getLogger("com.itheima");
通过名字可以看出logger1的父类是logger2
日志的配置文件
默认配置文件路径$JAVAHOME\jre\lib\logging.properties
@Test public void customProperties() throws IOException { //读取配置文件通过类加载器 InputStream is = JULlog.class.getClassLoader().getResourceAsStream("logging.properties"); //创建LogManager LogManager logManager = LogManager.getLogManager(); //通过logManager加载配置文件 logManager.readConfiguration(is); Logger logger = Logger.getLogger("customlog"); logger.log(Level.SEVERE,"severe"); logger.log(Level.WARNING,"waring"); logger.log(Level.INFO,"info"); logger.log(Level.CONFIG,"config"); logger.log(Level.FINE,"FINE"); logger.log(Level.FINER,"FINER"); logger.log(Level.FINEST,"FINEST11"); logger.log(Level.INFO,"ip:110.110.110.100, 访问:/6666"); }
配置文件
日志原理解析
1.
初始化
LogManager
1. LogManager
加载
logging.properties
配置
2.
添加
Logger
到
LogManager
2.
从单例
LogManager
获取
Logger
3.
设置级别
Level
,并指定日志记录
LogRecord
4. Filter
提供了日志级别之外更细粒度的控制
5. Handler
是用来处理日志输出位置
6. Formatter
是用来格式化
LogRecord
的
![](https://img-blog.csdnimg.cn/direct/6933ff0e8b6d4dc8a77063f8e0a1937a.png)
简单流程:初始化logger -->根据过滤级别过滤日志-->通过Handler控制日志输出的位置-->Formatter控制日志输出的格式-->输出日志
到这里整个JUL的学习就结束的,如果有不足的地方,欢迎指出,如果有帮助,欢迎点赞