• JUL 学习


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

    1、JUL入门

    1.1、架构介绍

    • 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的过滤,判断哪些日志级别过滤放行哪些拦截,andler会将日志内容输出到指定位置(日志文件、控制台等)。Handler在输出日志时会使用Layout,将输出内容进行排版。

    1.2、入门案例

    1. public class JULTest {
    2. @Test
    3. public void testQuick() throws Exception {
    4. // 1.创建日志记录器对象
    5. Logger logger = Logger.getLogger("com.itheima.log.JULTest");
    6. // 2.日志记录输出
    7. logger.info("hello jul");
    8. // 通用方法进行日志记录
    9. logger.log(Level.INFO, "info msg");
    10. // 通过占位符方式输出变量值
    11. String name = "jack";
    12. Integer age = 18;
    13. logger.log(Level.INFO, "用户信息:{0},{1}", new Object[]{name, age});
    14. }
    15. }

    2、日志的级别

    jul中定义的日志级别

    * java.util.logging.Level中定义了日志的级别:
                    SEVERE(最高值)
                    WARNING
                    INFO (默认级别)
                    CONFIG
                    FINE
                    FINER
                    FINEST(最低值)

    * 还有两个特殊的级别:
                    OFF,可用来关闭日志记录。
                    ALL,启用所有消息的日志记录。

    虽然我们测试了7个日志级别但是默认只实现info以上的级别

    1. @Test
    2. public void testLogLevel() throws Exception {
    3. // 1.获取日志对象
    4. Logger logger = Logger.getLogger("com.itheima.log.QuickTest");
    5. // 2.日志记录输出
    6. logger.severe("severe");
    7. logger.warning("warning");
    8. logger.info("info");
    9. logger.config("cofnig");
    10. logger.fine("fine");
    11. logger.finer("finer");
    12. logger.finest("finest");
    13. }

    自定义日志级别配置

    1. @Test
    2. public void testLogConfig() throws Exception {
    3. // 1.创建日志记录器对象
    4. Logger logger = Logger.getLogger("com.itheima.log.JULTest");
    5. // 一、自定义日志级别
    6. // a.关闭系统默认配置
    7. logger.setUseParentHandlers(false);
    8. // b.创建handler对象
    9. ConsoleHandler consoleHandler = new ConsoleHandler();// 输出到控制台
    10. // c.创建formatter对象
    11. SimpleFormatter simpleFormatter = new SimpleFormatter();
    12. // d.进行关联
    13. consoleHandler.setFormatter(simpleFormatter);
    14. logger.addHandler(consoleHandler);
    15. // e.设置日志级别
    16. logger.setLevel(Level.ALL);
    17. consoleHandler.setLevel(Level.ALL);
    18. // 二、输出到日志文件
    19. FileHandler fileHandler = new FileHandler("d:/logs/jul.log");
    20. fileHandler.setFormatter(simpleFormatter);
    21. logger.addHandler(fileHandler);
    22. // 2.日志记录输出
    23. logger.severe("severe");
    24. logger.warning("warning");
    25. logger.info("info");
    26. logger.config("config");
    27. logger.fine("fine");
    28. logger.finer("finer");
    29. logger.finest("finest");
    30. }

    3、Logger之间的父子关系

            JUL中Logger之间存在父子关系,这种父子关系通过树状结构存储,JUL在初始化时会创建一个顶层RootLogger作为所有Logger父Logger,存储上作为树状结构的根节点。并父子关系通过路径来关联。

    1. @Test
    2. public void testLogParent() throws Exception {
    3. // 日志记录器对象父子关系
    4. Logger logger1 = Logger.getLogger("com.itheima.log");
    5. Logger logger2 = Logger.getLogger("com.itheima");
    6. System.out.println(logger1.getParent() == logger2);
    7. // 所有日志记录器对象的顶级父元素 class为java.util.logging.LogManager$RootLogger name为""
    8. System.out.println("logger2 parent:" + logger2.getParent() + ",name:" + logger2.getParent().getName());
    9. // 一、自定义日志级别
    10. // a.关闭系统默认配置
    11. logger2.setUseParentHandlers(false);
    12. // b.创建handler对象
    13. ConsoleHandler consoleHandler = new ConsoleHandler();
    14. // c.创建formatter对象
    15. SimpleFormatter simpleFormatter = new SimpleFormatter();
    16. // d.进行关联
    17. consoleHandler.setFormatter(simpleFormatter);
    18. logger2.addHandler(consoleHandler);
    19. // e.设置日志级别
    20. logger2.setLevel(Level.ALL);
    21. consoleHandler.setLevel(Level.ALL);
    22. // 测试日志记录器对象父子关系
    23. logger1.severe("severe");
    24. logger1.warning("warning");
    25. logger1.info("info");
    26. logger1.config("config");
    27. logger1.fine("fine");
    28. logger1.finer("finer");
    29. logger1.finest("finest");
    30. }

    4、日志的配置文件

    默认配置文件路径$JAVAHOME\jre\lib\logging.properties

    1. @Test
    2. public void testProperties() throws Exception {
    3. // 读取自定义配置文件
    4. InputStream in = JULTest.class.getClassLoader().getResourceAsStream("logging.properties");
    5. // 获取日志管理器对象
    6. LogManager logManager = LogManager.getLogManager();
    7. // 通过日志管理器加载配置文件
    8. logManager.readConfiguration(in);
    9. Logger logger = Logger.getLogger("com.itheima.log.JULTest");
    10. logger.severe("severe");
    11. logger.warning("warning");
    12. logger.info("info");
    13. logger.config("config");
    14. logger.fine("fine");
    15. logger.finer("finer");
    16. logger.finest("finest");
    17. }

    配置文件:

    1. ## RootLogger使用的处理器(获取时设置)
    2. handlers= java.util.logging.ConsoleHandler
    3. # RootLogger日志等级
    4. .level= INFO
    5. ## 自定义Logger
    6. com.itheima.handlers= java.util.logging.FileHandler
    7. # 自定义Logger日志等级
    8. com.itheima.level= INFO
    9. # 忽略父日志设置
    10. com.itheima.useParentHandlers=false
    11. ## 控制台处理器
    12. # 输出日志级别
    13. java.util.logging.ConsoleHandler.level = INFO
    14. # 输出日志格式
    15. java.util.logging.ConsoleHandler.formatter = java.util.logging.SimpleFormatter
    16. # 指定handler对象的字符集
    17. java.util.logging.ConsoleHandler.encoding=UTF-8
    18. ## 文件处理器
    19. # 输出日志级别
    20. java.util.logging.FileHandler.level=INFO
    21. # 输出日志格式
    22. java.util.logging.FileHandler.formatter = java.util.logging.SimpleFormatter
    23. # 输出日志文件路径
    24. java.util.logging.FileHandler.pattern = /java%u.log
    25. java.util.logging.FileHandler.limit = 50000
    26. # 输出日志文件限制个数
    27. java.util.logging.FileHandler.count = 10
    28. # 输出日志文件 是否是追加
    29. java.util.logging.FileHandler.append=true

    5、日志原理解析

    1. 初始化LogManager
      1. LogManager加载logging.properties配置
      2. 添加Logger到LogManager
    2. 从单例LogManager获取Logger
    3. 设置级别Level,并指定日志记录LogRecord
    4. Filter提供了日志级别之外更细粒度的控制
    5. Handler是用来处理日志输出位置
    6. Formatter是用来格式化LogRecord的

  • 相关阅读:
    SpringMVC-HttpMessageConverter(请求体/响应体)/文件下载与上传)
    计算机领域期刊会议级别分类
    【Java】工具类的设计
    【MySQL】A01、性能优化-参数监控&分析
    sleep() 方法和 wait() 方法对比
    直播的多样性
    奶牛排序问题
    玩转ASP.NET 6.0框架-序言
    PHP原生类总结利用
    Windows终端配置emoji
  • 原文地址:https://blog.csdn.net/weixin_52851967/article/details/126052186