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

本文涉及的产品
日志服务 SLS,月写入数据量 50GB 1个月
简介: 【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之间存在父子关系,这是为了实现日志记录的层次结构和更方便的配置管理。这种父子关系的设计使得日志记录器可以继承和继承配置。

相关实践学习
日志服务之使用Nginx模式采集日志
本文介绍如何通过日志服务控制台创建Nginx模式的Logtail配置快速采集Nginx日志并进行多维度分析。
目录
相关文章
|
4月前
|
Java 数据库
在Java中使用Seata框架实现分布式事务的详细步骤
通过以上步骤,利用 Seata 框架可以实现较为简单的分布式事务处理。在实际应用中,还需要根据具体业务需求进行更详细的配置和处理。同时,要注意处理各种异常情况,以确保分布式事务的正确执行。
|
4月前
|
消息中间件 Java Kafka
在Java中实现分布式事务的常用框架和方法
总之,选择合适的分布式事务框架和方法需要综合考虑业务需求、性能、复杂度等因素。不同的框架和方法都有其特点和适用场景,需要根据具体情况进行评估和选择。同时,随着技术的不断发展,分布式事务的解决方案也在不断更新和完善,以更好地满足业务的需求。你还可以进一步深入研究和了解这些框架和方法,以便在实际应用中更好地实现分布式事务管理。
|
3月前
|
存储 安全 Java
Java 集合框架中的老炮与新秀:HashTable 和 HashMap 谁更胜一筹?
嗨,大家好,我是技术伙伴小米。今天通过讲故事的方式,详细介绍 Java 中 HashMap 和 HashTable 的区别。从版本、线程安全、null 值支持、性能及迭代器行为等方面对比,帮助你轻松应对面试中的经典问题。HashMap 更高效灵活,适合单线程或需手动处理线程安全的场景;HashTable 较古老,线程安全但性能不佳。现代项目推荐使用 ConcurrentHashMap。关注我的公众号“软件求生”,获取更多技术干货!
61 3
|
1月前
|
存储 缓存 Java
java语言后台管理ruoyi后台管理框架-登录提示“无效的会话,或者会话已过期,请重新登录。”-扩展知识数据库中密码加密的方法-问题如何解决-以及如何重置若依后台管理框架admin密码-优雅草卓伊凡
java语言后台管理ruoyi后台管理框架-登录提示“无效的会话,或者会话已过期,请重新登录。”-扩展知识数据库中密码加密的方法-问题如何解决-以及如何重置若依后台管理框架admin密码-优雅草卓伊凡
110 3
java语言后台管理ruoyi后台管理框架-登录提示“无效的会话,或者会话已过期,请重新登录。”-扩展知识数据库中密码加密的方法-问题如何解决-以及如何重置若依后台管理框架admin密码-优雅草卓伊凡
|
7天前
|
存储 监控 数据可视化
SaaS云计算技术的智慧工地源码,基于Java+Spring Cloud框架开发
智慧工地源码基于微服务+Java+Spring Cloud +UniApp +MySql架构,利用传感器、监控摄像头、AI、大数据等技术,实现施工现场的实时监测、数据分析与智能决策。平台涵盖人员、车辆、视频监控、施工质量、设备、环境和能耗管理七大维度,提供可视化管理、智能化报警、移动智能办公及分布计算存储等功能,全面提升工地的安全性、效率和质量。
|
2月前
|
并行计算 算法 Java
Java中的Fork/Join框架详解
Fork/Join框架是Java并行计算的强大工具,尤其适用于需要将任务分解为子任务的场景。通过正确使用Fork/Join框架,可以显著提升应用程序的性能和响应速度。在实际应用中,应结合具体需求选择合适的任务拆分策略,以最大化并行计算的效率。
66 23
|
4月前
|
存储 缓存 安全
Java 集合框架优化:从基础到高级应用
《Java集合框架优化:从基础到高级应用》深入解析Java集合框架的核心原理与优化技巧,涵盖列表、集合、映射等常用数据结构,结合实际案例,指导开发者高效使用和优化Java集合。
85 4
|
20天前
|
存储 缓存 关系型数据库
图解MySQL【日志】——Redo Log
Redo Log(重做日志)是数据库中用于记录数据页修改的物理日志,确保事务的持久性和一致性。其主要作用包括崩溃恢复、提高性能和保证事务一致性。Redo Log 通过先写日志的方式,在内存中缓存修改操作,并在适当时候刷入磁盘,减少随机写入带来的性能损耗。WAL(Write-Ahead Logging)技术的核心思想是先将修改操作记录到日志文件中,再择机写入磁盘,从而实现高效且安全的数据持久化。Redo Log 的持久化过程涉及 Redo Log Buffer 和不同刷盘时机的控制参数(如 `innodb_flush_log_at_trx_commit`),以平衡性能与数据安全性。
28 5
图解MySQL【日志】——Redo Log
|
4月前
|
XML 安全 Java
【日志框架整合】Slf4j、Log4j、Log4j2、Logback配置模板
本文介绍了Java日志框架的基本概念和使用方法,重点讨论了SLF4J、Log4j、Logback和Log4j2之间的关系及其性能对比。SLF4J作为一个日志抽象层,允许开发者使用统一的日志接口,而Log4j、Logback和Log4j2则是具体的日志实现框架。Log4j2在性能上优于Logback,推荐在新项目中使用。文章还详细说明了如何在Spring Boot项目中配置Log4j2和Logback,以及如何使用Lombok简化日志记录。最后,提供了一些日志配置的最佳实践,包括滚动日志、统一日志格式和提高日志性能的方法。
1189 31
【日志框架整合】Slf4j、Log4j、Log4j2、Logback配置模板
|
3月前
|
监控 安全 Apache
什么是Apache日志?为什么Apache日志分析很重要?
Apache是全球广泛使用的Web服务器软件,支持超过30%的活跃网站。它通过接收和处理HTTP请求,与后端服务器通信,返回响应并记录日志,确保网页请求的快速准确处理。Apache日志分为访问日志和错误日志,对提升用户体验、保障安全及优化性能至关重要。EventLog Analyzer等工具可有效管理和分析这些日志,增强Web服务的安全性和可靠性。