JUL 日志 (全面,详细)

JUL全称Java util Logging是java原生的日志框架,使用时不需要另外引用第三方类库,相对其他日志框 架使用方便,学习简单,能够在小型应用中灵活使用。
JUL在项目开发中用的比较少了,因为它的功能有点单一,无法满足项目中一些复杂的需求(比如输出的日志文件按时间存储,这个它是无法实现的),但作为学习,了解一下他是怎么实现的,也是一个不错的方式

架构介绍

  • Loggers:被称为记录器,应用程序通过获取Logger对象,调用其API来来发布日志信息。Logger通常时应用程序访问日志系统的入口程序。
  • Appenders:也被称为Handlers,每个Logger都会关联一组HandlersLogger会将日志交给关联 Handlers处理,由Handlers负责将日志做记录。Handlers在此是一个抽象,其具体的实现决定了日志记录的位置可以是控制台、文件、网络上的其他日志服务或操作系统日志等。
  • Layouts:也被称为Formatters,它负责对日志事件中的数据进行转换和格式化。Layouts决定了数据在一条日志记录中的最终形式。
  • Level:每条日志消息都有一个关联的日志级别。该级别粗略指导了日志消息的重要性和紧迫,我可以将LevelLoggersAppenders做关联以便于我们过滤消息。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

 简单流程:初始化logger -->根据过滤级别过滤日志-->通过Handler控制日志输出的位置-->Formatter控制日志输出的格式-->输出日志

到这里整个JUL的学习就结束的,如果有不足的地方,欢迎指出,如果有帮助,欢迎点赞

  • 5
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

smilehjl

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值