Java常用日志框架--JUL

1. 日志文件分类

1.1.调试日志

调试日志在开发过程中调试程序,输出的日志。

2.1系统日志

系统日志是用来记录系统中硬件、软件和系统相关问题的信息。同时还可以监视系统中发生的事件。用户可以通过它来检查错误发生的原因,或者寻找收到攻击时留下的痕迹。系统日志包括系统日志、应用日志和安全日志这几种分类。

2. 日志框架概述

2.1 日志框架的作用

(1)控制日志输出的内容和格式。
(2)控制日志输出的位置。
(3)日志文件相关的优化,如异步、归档、压缩。
(4)日志系统的维护。
(5)面向接口开发–日志的门面。

2.2 市面流行的日志框架

JUL java util logging: Java原生日志框架
Log4j: Apache的一个开源项目
Logback: 由Log4j之父做的另一个开源项目,一个可靠、通用且灵活的java日志框架
Log4j2: Log4j官方的第二个版本,各个方面都是与Logback及其相似。具有插件式结构、配置文件优化等特征,Spring Boot1.4 版本以后就不再支持log4j,所以第二个版本应运而生

2.3 日志门面技术

日志门面技术 JCL、SLF4j

2.4 为什么要使用日志门面技术

4.1 降低代码和日志框架的耦合性:日志门面技术需要配合日志框架使用,并且可以做到在不改动代码的情况下,可以切换日志框架。

不同的项目调用不同的日志框架
抽取出方法c,其实内部调用的还是各自记录日志的方法。
在这里插入图片描述

3. 日志框架详解

3.1 JUL简介

JUL是Java自带的框架,使用时不需要另外引用第三方的类库,相对其他框架使用简单,主要是使用在小型应用中,我看公司的代码比较老的项目用的是这个框架。

3.2 JUL组件介绍

在这里插入图片描述
Logger:被称为记录器,应用程序通过获取Logger对象,调用其API来发布日志信息。Logger通常被认为是访问日志系统的入口程序。
Handler:处理器,每个Logger都会关联一个或者是一组Handler,Logger会将日志交给关联的Handler去做处理,由Handler负责将日志做记录。Handler具体实现了日志的输出位置,比如可以输出到控制台或者文件中等等。
Filter:过滤器,根据需要定制哪些信息会被记录,哪些信息会被略过。
Formatter:格式化组件,它负责对日志中的数据和信息进行转换和格式化,所以它决定了我们日志输出最终的形式。
Level:日志的输出级别,每条日志消息都有一个关联的级别。我们根据输出级别的设置,用来展现最终所呈现的日志信息。

3.3 JUL组件案例

3.3.1 JUL组件案例

1)Logger对象的创建方式:不能直接new 对象,用getLogger方法获取logger对象。

//com.form.project.test.LogDemoCtroller为当前类的全路径
 Logger logger = Logger.getLogger("com.form.project.test.LogDemoCtroller");

2)日志的两种输出方式:

//方式一:直接调用日志级别相关的方法,方法中传递日志输出信息
logger.info("输出info信息1");

//方式二:调用通用的log方法,然后在里面通过level类型来定义日志的级别参数,以及搭配日志输出信息的参数。
logger.log(Level.INFO,"输出info信息2");

3)日志中的占位符

        /**
         * 我们可以使用字符串拼接的方式输出学生信息 姓名 年龄
         */
        String name = "张三";
        int age = 23;
        logger.log(Level.INFO,"学生的姓名为:"+name+";年龄为:"+age);

但是字符串拼接的方式程序效率低,可读性不强,维护成本高,所以我们可以使用占位符的方式来进行操作。

		//0表示是第一个占位符 1表示第二个占位符
		String name = "张三";
        int age = 23;
        logger.log(Level.INFO,"学生的姓名:{0},年龄:{1}",new Object[]{name,age});

3.3.2 JUL日志的级别

1)JUL日志的级别

          SEVERE:(最高级)错误 ----最高级的日志级别
          WARNING:警告
          INFO:(默认级别)消息
          CONFIG:配置
          FINE:详细信息(少)
          FINER:详细信息(中)
          FINEST:详细信息(多)----最低级的日志级别
 		 两个特殊的级别
         OFF: 可用来关闭日志记录
         ALL:  启用所有消息的日志记录
/**
* 我们可以看到第二个参数是数值,数值的意义在于,如果我们设置的日志的级别是INFO--800
* 那么最终展现的日志信息,必须是数值大于800的所有日志信息
* 即打印出的级别为:INFO、WARNING、SEVERE
**/
//部分日志级别源码:
 	public static final Level SEVERE = new Level("SEVERE",1000, defaultBundle);

    public static final Level WARNING = new Level("WARNING", 900, defaultBundle);

    public static final Level INFO = new Level("INFO", 800, defaultBundle);

    public static final Level CONFIG = new Level("CONFIG", 700, defaultBundle);

    public static final Level FINE = new Level("FINE", 500, defaultBundle);

    public static final Level FINER = new Level("FINER", 400, defaultBundle);

    public static final Level FINEST = new Level("FINEST", 300, defaultBundle);

2)默认的日志级别
默认的日志级别为info,我们下面代码程序中有7个日志级别,但是输出只有3个日志级别,说明默认的日志级别是info,这样就是输出了info及以上的信息。

 Logger logger = Logger.getLogger("com.form.project.test.LogDemoCtroller");
        logger.severe("severe信息");
        logger.warning("warning信息");
        logger.info("info信息");
        logger.config("config信息");
        logger.fine("fine信息");
        logger.finer("finer信息");
        logger.finest("finest信息");
 输出:
 九月 17, 2022 5:30:32 下午 com.form.project.test.LogDemoCtroller test02
 严重: severe信息
 九月 17, 2022 5:30:32 下午 com.form.project.test.LogDemoCtroller test02
 警告: warning信息
 九月 17, 2022 5:30:32 下午 com.form.project.test.LogDemoCtroller test02
 信息: info信息       

3)自定义日志级别

        Logger.getLogger("com.form.project.test.LogDemoCtroller");
        //将默认的日志打印方式关闭掉
        //参数设置为flase,我们打印日志的方式就不会按照父logger默认的方式进行操作
        logger.setUseParentHandlers(false);

        //处理器Handler
        //在此我们使用的是控制台日志处理器,取得处理器对象
        ConsoleHandler handler = new ConsoleHandler();
        //创建日志格式化组件对象
        SimpleFormatter formatter = new SimpleFormatter();

        //在处理器中设置输出格式
        handler.setFormatter(formatter);
        //在记录器中添加处理器
        logger.addHandler(handler);

        //设置日志的打印级别
        //此处必须将日志记录器和处理器的级别进行统一的设置,才会达到日志显示相应级别的效果
        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信息");
输出:
九月 17, 2022 8:25:50 下午 com.form.project.test.LogDemoCtroller test02
严重: severe信息
九月 17, 2022 8:25:50 下午 com.form.project.test.LogDemoCtroller test02
警告: warning信息
九月 17, 2022 8:25:50 下午 com.form.project.test.LogDemoCtroller test02
信息: info信息
九月 17, 2022 8:25:50 下午 com.form.project.test.LogDemoCtroller test02
配置: config信息
九月 17, 2022 8:25:50 下午 com.form.project.test.LogDemoCtroller test02
详细: fine信息
九月 17, 2022 8:25:50 下午 com.form.project.test.LogDemoCtroller test02
较详细: finer信息
九月 17, 2022 8:25:50 下午 com.form.project.test.LogDemoCtroller test02
非常详细: finest信息

3.3.3 JUL文件日志

1)JUL文件日志的打印

    @Test
    public void test03() throws IOException {
        /*
          将日志输出到具体的磁盘文件中
          这样做相当于是做了日志的持久化操作
         */
        Logger logger = Logger.getLogger("com.form.project.test.LogDemoCtroller");
        logger.setUseParentHandlers(false);

        //文件日志处理器
        FileHandler fileHandler = new FileHandler("/Users/chezhewei/Desktop/mylog.log");

        //创建日志格式化组件对象
        SimpleFormatter formatter = new SimpleFormatter();

        //在处理器中设置输出格式
        fileHandler.setFormatter(formatter);
        //在记录器中添加处理器
        logger.addHandler(fileHandler);

        logger.severe("severe信息");
        logger.warning("warning信息");
        logger.info("info信息");
        logger.config("config信息");
        logger.fine("fine信息");
        logger.finer("finer信息");
        logger.finest("finest信息");
    }

在桌面生成了log日志文件,如图所示
请添加图片描述
文件中的内容为:

九月 17, 2022 8:50:03 下午 com.form.project.test.LogDemoCtroller test03
严重: severe信息
九月 17, 2022 8:50:03 下午 com.form.project.test.LogDemoCtroller test03
警告: warning信息
九月 17, 2022 8:50:03 下午 com.form.project.test.LogDemoCtroller test03
信息: info信息

日志的打印只是将控制台处理器变成了文件处理器,也可以同时设置控制台处理和文件处理,也就是同时添加多个处理器。

 public void test03() throws IOException {
        /*
          将日志输出到具体的磁盘文件中
          这样做相当于是做了日志的持久化操作
         */
        Logger logger = Logger.getLogger("com.form.project.test.LogDemoCtroller");
        logger.setUseParentHandlers(false);

        //文件日志处理器
        FileHandler fileHandler = new FileHandler("/Users/chezhewei/Desktop/mylog.log");
        //创建日志格式化组件对象
        SimpleFormatter formatter = new SimpleFormatter();
        //在处理器中设置输出格式
        fileHandler.setFormatter(formatter);
        //在记录器中添加处理器
        logger.addHandler(fileHandler);

		//同时设置在控制台和文件中进行打印
		ConsoleHandler handler = new ConsoleHandler();
		//在处理器中设置输出格式
        handler.setFormatter(formatter);
        //在记录器中添加处理器
        logger.addHandler(handler);

        logger.severe("severe信息");
        logger.warning("warning信息");
        logger.info("info信息");
        logger.config("config信息");
        logger.fine("fine信息");
        logger.finer("finer信息");
        logger.finest("finest信息");
 }

3.3.4 JUL Logger的父子关系

Logger之间的"父子"关系,这种父子关系不是继承关系,是通过树状结构存储的(代码包的层级)。
RootLogger是所有logger对象的顶层logger,logger1的父类也为RootLogger。
JUL在初始化时,会创建一个顶层RootLogger作为所有Logger的父Logger
查看源码:
owner.rootLogger = owner.new RootLogger();
rootLogger是LogManager的内部类
java.util.logging.LogManager$RootLogger默认名称为 空串
父子关系同时也是节点之间的挂载关系
LoggerContext cx = getUserContext();//LoggerContext 一种用来保存节点的Map关系
private LogNode node;//节点

Logger logger1 = Logger.getLogger("com.form.project.test");//父(父logger的父亲是RootLogger)
Logger logger2 = Logger.getLogger("com.form.project.test.LogDemoCtroller");//子

 //System.out.println(logger2.getParent() == logger1);//输出为true
 System.out.println("logger1的父logger引用为:"+logger1.getParent()+";父亲的名称为"+logger1.getParent().getName());
 System.out.println("logger2的父logger引用为:"+logger2.getParent()+";父亲的名称为"+logger2.getParent().getName());
 输出为:
 logger1的父logger引用为:java.util.logging.LogManager$RootLogger@1c72da34;父亲的名称为
 logger2的父logger引用为:java.util.logging.Logger@6b0c2d26;父亲的名称为com.tang.project1.test


  /*
  父亲所做的设置,也能够同时作用于儿子
  对logger1做的日志打印相关的设置,然后我们使用logger2进行日志的打印
   */
  //父类做输出
   logger1.setUseParentHandlers(false);
   ConsoleHandler handler = new ConsoleHandler();
   SimpleFormatter formatter = new SimpleFormatter();
   handler.setFormatter(formatter);
   logger1.addHandler(handler);

   logger1.setLevel(Level.ALL);
    handler.setLevel(Level.ALL);

    //子类做打印
    logger2.severe("severe信息");
    logger2.warning("warning信息");
    logger2.info("info信息");
    logger2.config("config信息");
    logger2.fine("fine信息");
    logger2.finer("finer信息");
    logger2.finest("finest信息");
输出如下:
九月 17, 2022 9:46:04 下午 com.form.project.test.LogDemoCtroller test04
严重: severe信息
九月 17, 2022 9:46:04 下午 com.form.project.test.LogDemoCtroller test04
警告: warning信息
九月 17, 2022 9:46:04 下午 com.form.project.test.LogDemoCtroller test04
信息: info信息
九月 17, 2022 9:46:04 下午 com.form.project.test.LogDemoCtroller test04
配置: config信息
九月 17, 2022 9:46:04 下午 com.form.project.test.LogDemoCtroller test04
详细: fine信息
九月 17, 2022 9:46:04 下午 com.form.project.test.LogDemoCtroller test04
较详细: finer信息
九月 17, 2022 9:46:04 下午 com.form.project.test.LogDemoCtroller test04
非常详细: finest信息

3.3.5 JUL 配置文件位置

1)系统默认配置文件
以上所有的配置和相关的操作,都是以java硬编码的形式进行的我们可以使用更加清晰,更加专业的一种做法,就是使用配置文件。如果我们没有自己添加配置文件,则会使用系统默认的配置文件。
系统默认的配置文件在:jre–>lib–>logging.properties
默认配置文件信息解释:
请添加图片描述
请添加图片描述
2)使用自定义配置文件
使用自定义配置文件:

    @Test
    public void test06() throws IOException {
        InputStream inputStream = new FileInputStream("自定义配置文件地址");
        //取得日志管理器对象
        LogManager logManager = LogManager.getLogManager();
        //读取自定义配置文件
        logManager.readConfiguration(inputStream);
        Logger logger1 = Logger.getLogger("com.form.project.test.LogDemoCtroller");
        logger1.severe("severe信息");
        logger1.warning("warning信息");
        logger1.info("info信息");
        logger1.config("config信息");
        logger1.fine("fine信息");
        logger1.finer("finer信息");
        logger1.finest("finest信息");
    }

自定义配置文件的输出:
请添加图片描述
追加日志:
请添加图片描述

3.3 JUL日志框架使用方式总结(原理解析)

1) 初始化LogManager,LogManager加载logging.properties配置文件,添加Logger到LogManager
2)从单例的LogManager获取Logger
3)设置日志级别level.在打印的过程中使用到了日志记录的LogRecord类
4)Filter作为过滤器提供了日志级别之外更细粒度的控制。
5)Handler日志处理器。决定日志的输出位置.例如控制台、文件。。。
6)Formatter是用来格式化输出的

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值