【JAVA日志框架】JUL,JDK原生日志框架详解。

简介: 【JAVA日志框架】JUL,JDK原生日志框架详解。

1.概述

日志框架的核心问题:

日志是用来记录应用的一些运行信息的。假设没有日志框架,我们要在应用里手动实现日志相关功能,我们需要关注些什么?其实仔细想想无非两点:

  • 记录哪些信息?
  • 记录到哪里去?

当然作为日志框架来说,为了方便使用,它还要关注一点就是:

  • 如何进行方便的配置

java日志体系中是先有的log4j,后面才有了JDK自带的jul,两者是两套体系,互不兼容。但其实本质上jul就是抄的log4j,其架构上都是一模一样的。以上三点核心问题,我们看作为日志框架的开山鼻祖的log4j是怎样解决的:


log4j给出的答案是:

  • 记录哪些信息——日志级别(level)
  • 记录到哪里去——提供不同的输出方式(appender),文件、控制台、其它等等
  • 如何进行方便的配置——除硬编码外,提供配置文件

jul是一模一样的,其只是把appender改成了handler而已。

2.日志级别

package com.eryi;
 
import com.sun.scenario.effect.impl.sw.sse.SSEBlend_SRC_OUTPeer;
 
import java.util.logging.Level;
import java.util.logging.Logger;
 
public class Test {
    @org.junit.Test
    public void test1() {
      //级别由低到高,默认输出info以上级别
        Logger logger = Logger.getLogger("abc");
        logger.log(Level.FINEST,"FINEST level");
        logger.log(Level.FINER,"FINER level");
        logger.log(Level.FINE,"FINE level");
        logger.log(Level.CONFIG,"CONFIG level");
        logger.log(Level.INFO,"INFO level");
        logger.log(Level.WARNING,"WARNING level");
        logger.log(Level.SEVERE,"SEVERE level");
        logger.log(Level.FINEST,"FINEST level");
        System.out.println("hello");
    }
}

日志为什么是红色的?因为底层调用了system.erro,所以会输出的字体是红色的。

3.配置

可以用代码的方式对JUL进行配置:

public static void main(String[] args) {
        // 获取根记录器
        Logger rootLogger = Logger.getLogger("");
 
        // 移除默认处理器
        rootLogger.setUseParentHandlers(false);
 
        // 创建控制台处理器
        ConsoleHandler consoleHandler = new ConsoleHandler();
        
        // 设置级别
        consoleHandler.setLevel(Level.INFO);
 
        // 设置自定义格式器
        consoleHandler.setFormatter(new SimpleFormatter());
 
        // 设置自定义过滤器
        consoleHandler.setFilter(new CustomFilter());
 
        // 将处理器添加到根记录器
        rootLogger.addHandler(consoleHandler);
 
        // 输出日志
        Logger logger = Logger.getLogger(JULConfigExample.class.getName());
        logger.severe("Severe message");
        logger.warning("Warning message");
        logger.info("Info message");
        logger.config("Config message");
        logger.fine("Fine message");
        logger.finer("Finer message");
        logger.finest("Finest message");
    }
 
    // 自定义格式器
    static class SimpleFormatter extends Formatter {
        @Override
        public String format(LogRecord record) {
            return "[" + record.getLevel() + "] - " + record.getMessage() + "\n";
        }
    }
 
    // 自定义过滤器
    static class CustomFilter implements Filter {
        @Override
        public boolean isLoggable(LogRecord record) {
            // 在这里可以添加自定义的过滤逻辑
            return record.getLevel().intValue() >= Level.INFO.intValue();
        }
    }

当然更合理、更方便的方式肯定是配置文件。配置文件的示例模板在jre/lib目录下:

把它拷贝过来改一下:

#默认配置
handlers= java.util.logging.ConsoleHandler
.level= FINEST
 
#file hander配置
java.util.logging.FileHandler.pattern = %h/java%u.log
java.util.logging.FileHandler.limit = 50000
java.util.logging.FileHandler.count = 1
java.util.logging.FileHandler.formatter = java.util.logging.XMLFormatter
 
#console handler配置
java.util.logging.ConsoleHandler.level = FINEST
java.util.logging.ConsoleHandler.formatter = java.util.logging.SimpleFormatter
 
# 具体包路径下的日志级别
com.eryi.level = FINEST

解读一下配置:

  1. 默认配置:
  • handlers: 指定默认的处理器,这里是java.util.logging.ConsoleHandler,表示使用控制台输出。
  • .level: 设置默认的日志级别,这里是FINEST,表示记录最详细的日志。

File Handler配置:

  • java.util.logging.FileHandler.pattern: 设置文件处理器的日志文件的命名模式,%h表示用户主目录,%u表示一个唯一的数值,%g表示循环计数器。这里是 %h/java%u.log。
  • java.util.logging.FileHandler.limit: 设置文件处理器的每个日志文件的大小限制,这里是 50000 字节。
  • java.util.logging.FileHandler.count: 设置文件处理器循环的文件数,这里是 1 个。
  • java.util.logging.FileHandler.formatter: 设置文件处理器的日志格式,这里是 java.util.logging.XMLFormatter,表示使用 XML 格式。
  1. Console Handler配置:
  • java.util.logging.ConsoleHandler.level: 设置控制台处理器的日志级别,这里是 FINEST。
  • java.util.logging.ConsoleHandler.formatter: 设置控制台处理器的日志格式,这里是 java.util.logging.SimpleFormatter,表示使用简单格式。
  1. 具体包路径下的日志级别:
  • com.eryi.level: 设置特定包路径下的日志级别,这里是 FINEST,表示 com.eryi 包下的日志级别为最详细。

这里要说一下为什么有了.level的配置之后还推出了专门指定某个包路径下日志级别的配置。是因为logger之间是有父子关系的。.level会对根logger生效,其余logger是继承自根logger的,但肯定工程上不一定是全局日志级别都是一致的,会有需求需要单独定制某一个或者某一些的logger的日志级别。

使用效果如下:

4.继承关系

logger之间存在父子关系。

root logger是最顶层的父logger:

Logger a = Logger.getLogger("a");
Logger b = Logger.getLogger("b");
System.out.println(a.getParent());
System.out.println(b.getParent());

通过父名·子名定义父子关系:

Logger a = Logger.getLogger("a");
Logger b = Logger.getLogger("a.b");
System.out.println(a.getParent());
System.out.println(b.getParent()==a);

为什么在设计的时候会存在父子关系?

Java Util Logging(JUL)的Logger之间存在父子关系,这是为了实现日志记录的层次结构和更方便的配置管理。这种父子关系的设计使得日志记录器可以继承和继承配置。

相关实践学习
【涂鸦即艺术】基于云应用开发平台CAP部署AI实时生图绘板
【涂鸦即艺术】基于云应用开发平台CAP部署AI实时生图绘板
目录
相关文章
|
12月前
|
安全 前端开发 Java
《深入理解Spring》:现代Java开发的核心框架
Spring自2003年诞生以来,已成为Java企业级开发的基石,凭借IoC、AOP、声明式编程等核心特性,极大简化了开发复杂度。本系列将深入解析Spring框架核心原理及Spring Boot、Cloud、Security等生态组件,助力开发者构建高效、可扩展的应用体系。(238字)
|
12月前
|
存储 安全 Java
《数据之美》:Java集合框架全景解析
Java集合框架是数据管理的核心工具,涵盖List、Set、Map等体系,提供丰富接口与实现类,支持高效的数据操作与算法处理。
|
消息中间件 缓存 Java
Spring框架优化:提高Java应用的性能与适应性
以上方法均旨在综合考虑Java Spring 应该程序设计原则, 数据库交互, 编码实践和系统架构布局等多角度因素, 旨在达到高效稳定运转目标同时也易于未来扩展.
961 8
|
存储 算法 安全
Java集合框架:理解类型多样性与限制
总之,在 Java 题材中正确地应对多样化与约束条件要求开发人员深入理解面向对象原则、范式编程思想以及JVM工作机理等核心知识点。通过精心设计与周密规划能够有效地利用 Java 高级特征打造出既健壮又灵活易维护系统软件产品。
312 7
|
人工智能 Java 开发者
阿里出手!Java 开发者狂喜!开源 AI Agent 框架 JManus 来了,初次见面就心动~
JManus是阿里开源的Java版OpenManus,基于Spring AI Alibaba框架,助力Java开发者便捷应用AI技术。支持多Agent框架、网页配置、MCP协议及PLAN-ACT模式,可集成多模型,适配阿里云百炼平台与本地ollama。提供Docker与源码部署方式,具备无限上下文处理能力,适用于复杂AI场景。当前仍在完善模型配置等功能,欢迎参与开源共建。
3709 58
阿里出手!Java 开发者狂喜!开源 AI Agent 框架 JManus 来了,初次见面就心动~
|
SQL Java 数据库连接
区分iBatis与MyBatis:两个Java数据库框架的比较
总结起来:虽然从技术角度看,iBATIS已经停止更新但仍然可用;然而考虑到长期项目健康度及未来可能需求变化情况下MYBATISS无疑会是一个更佳选择因其具备良好生命周期管理机制同时也因为社区力量背书确保问题修复新特征添加速度快捷有效.
988 12
|
存储 缓存 安全
Java集合框架(三):Map体系与ConcurrentHashMap
本文深入解析Java中Map接口体系及其实现类,包括HashMap、ConcurrentHashMap等的工作原理与线程安全机制。内容涵盖哈希冲突解决、扩容策略、并发优化,以及不同Map实现的适用场景,助你掌握高并发编程核心技巧。
|
XML 消息中间件 JSON
最牛逼的 Java 日志框架,性能无敌,横扫所有对手.....
最牛逼的 Java 日志框架,性能无敌,横扫所有对手.....
495 0
最牛逼的 Java 日志框架,性能无敌,横扫所有对手.....
|
XML 消息中间件 JSON
最牛逼的 Java 日志框架,性能无敌,横扫所有对手。。
Logback 算是JAVA 里一个老牌的日志框架,从06年开始第一个版本,迭代至今也十几年了。不过logback最近一个稳定版本还停留在 2017 年,好几年都没有更新;logback的兄弟 slf4j 最近一个稳定版也是2017年,有点凉凉的意思。 而且 logback的异步性能实在拉跨,功能简陋,配置又繁琐,远不及Apache 的新一代日志框架 - Log4j2 目前来看,Log4j2 就是王者,其他日志框架都不是对手
434 0
最牛逼的 Java 日志框架,性能无敌,横扫所有对手。。
|
JSON 网络协议 安全
【Java】(10)进程与线程的关系、Tread类;讲解基本线程安全、网络编程内容;JSON序列化与反序列化
几乎所有的操作系统都支持进程的概念,进程是处于运行过程中的程序,并且具有一定的独立功能,进程是系统进行资源分配和调度的一个独立单位一般而言,进程包含如下三个特征。独立性动态性并发性。
631 1