当前位置: 首页 > news >正文

Java 日志演进:一文读懂主流框架

目录

一、引入

二、核心概念:日志门面与日志实现

三、日志框架的发展历程

3.1 Log4j

3.1.1 日志级别

3.1.2 使用方式

1)添加依赖

2)配置文件

3) 在代码中使用

3.1.3 定位

3.2 JUL(简单了解)

3.2.1 日志级别

3.2.2 使用方式

3.2.3 定位

3.3 JCL(简单了解)

3.3.1 日志级别

3.3.2 使用方式

1)导入依赖

2)代码中使用

3.4 SLF4J(⭐)

3.3.1 日志级别

3.3.2 使用方式

3.5 Logback-slf4j(⭐)

3.6 Log4j2-slf4j(⭐)

3.6.1 日志级别

3.6.2 使用方式

1)配置文件

2)代码中使用

今日份冷笑话


本文主要向大家介绍下Java开发中一个很熟悉的伙伴--日志。

日志究竟是怎么延申发展起来的呢,它又为我们的日常开发究竟带来了多少便利?
下面我将通过日志发展历程顺序来逐一讲解这些日志的使用方式 ദ്ദി˶ー̀֊ー́ )✧

一、引入

💡假设你开发了一个简单的用户注册功能,并且在代码中通过硬编码打印了一些基础的语句信息。
这时用户反馈 “注册失败”,你去看控制台,只显示 “保存失败”,但不知道是数据库连接超时?还是手机号重复?完全无法定位问题。
于是聪明的你就想到了用日志框架替代硬编码打印,并在注册代码里按级别加了日志,以后排查问题就能看到具体原因,甚至生产环境没有控制台,也能通过日志文件追溯到问题。

二、核心概念:日志门面与日志实现

在讨论具体技术之前,必须要理解现代Java日志体系的核心思想:“门面模式”。它将日志API(接口)和日志(具体)实现分离。
  • 日志门面:提供一套统一的API,你的应用程序代码只依赖这些接口。这样做的好处就是:即使将来需要更换底层的日志实现,你的业务代码也完全不需要修改。
  • 日志实现:具体的日志库,负责实现前面提到的门面接口,完成实际的日志输出工作。
可以看到日志框架这么设计,本质还是为了灵活和可维护。

三、日志框架的发展历程

3.1 Log4j

Log4j作为日志框架的第一阶段,这也是Java社区第一个广泛使用、功能完善的日志框架,不过这个1.x已经在2015年停止维护了。

3.1.1 日志级别

Log4j定义了以下级别,级别从低到高依此为:
all→trace→debug→INFO→WARN→ERROR→fatal→off
规则:Logger只输出高于或等于其配置级别的日志。
比如,如果配置为 INFO,则会输出 INFO, WARN, ERROR, FATAL 级别的日志,而不会输出 DEBUG, TRACE

3.1.2 使用方式

log4j我就简单演示一下使用,因为这个目前已经不推荐使用了。
1)添加依赖
<dependency><groupId>log4j</groupId><artifactId>log4j</artifactId><version>1.2.17</version>
</dependency>
2)配置文件
log4j的核心就是配置,在配置中定义了日志输出的目的地和格式。
# 根日志器:级别DEBUG,输出到控制台和全局文件(所有未单独配置的日志都会走这里)
log4j.rootLogger = DEBUG, CONSOLE, GLOBAL_FILE# ========================= 公共输出源配置 =========================
# 1. 控制台输出(所有日志共享)
log4j.appender.CONSOLE = org.apache.log4j.ConsoleAppender
log4j.appender.CONSOLE.Target = System.out
log4j.appender.CONSOLE.layout = org.apache.log4j.PatternLayout
log4j.appender.CONSOLE.layout.ConversionPattern = %d{yyyy-MM-dd HH:mm:ss} %-5p %c{1}:%L - %m%n# 2. 全局文件输出(记录所有日志,含未单独配置的模块)
log4j.appender.GLOBAL_FILE = org.apache.log4j.RollingFileAppender
log4j.appender.GLOBAL_FILE.File = ./logs/global.log  # 全局日志文件
log4j.appender.GLOBAL_FILE.MaxFileSize = 10MB
log4j.appender.GLOBAL_FILE.MaxBackupIndex = 10
log4j.appender.GLOBAL_FILE.layout = org.apache.log4j.PatternLayout
log4j.appender.GLOBAL_FILE.layout.ConversionPattern = %d{yyyy-MM-dd HH:mm:ss} %-5p %c{1}:%L - %m%n# ========================= 模块专属日志配置 =========================
# 1. service模块:单独输出到service.log,不继承根日志的文件输出(避免重复)
# 定义service模块的日志器
log4j.logger.com.example.service = DEBUG, SERVICE_FILE
log4j.additivity.com.example.service = false  # 禁止继承根日志的输出源(只走自己的配置)# 配置service模块的文件输出源
log4j.appender.SERVICE_FILE = org.apache.log4j.RollingFileAppender
log4j.appender.SERVICE_FILE.File = ./logs/service.log  # service模块专属日志
log4j.appender.SERVICE_FILE.MaxFileSize = 10MB
log4j.appender.SERVICE_FILE.MaxBackupIndex = 10
log4j.appender.SERVICE_FILE.layout = org.apache.log4j.PatternLayout
log4j.appender.SERVICE_FILE.layout.ConversionPattern = %d{yyyy-MM-dd HH:mm:ss} %-5p %c{1}:%L - %m%n# 2. dao模块:单独输出到dao.log,同样不继承根日志的文件输出
# 定义dao模块的日志器
log4j.logger.com.example.dao = DEBUG, DAO_FILE
log4j.additivity.com.example.dao = false  # 禁止继承根日志的输出源# 配置dao模块的文件输出源
log4j.appender.DAO_FILE = org.apache.log4j.RollingFileAppender
log4j.appender.DAO_FILE.File = ./logs/dao.log  # dao模块专属日志
log4j.appender.DAO_FILE.MaxFileSize = 10MB
log4j.appender.DAO_FILE.MaxBackupIndex = 10
log4j.appender.DAO_FILE.layout = org.apache.log4j.PatternLayout
log4j.appender.DAO_FILE.layout.ConversionPattern = %d{yyyy-MM-dd HH:mm:ss} %-5p %c{1}:%L - %m%n
3) 在代码中使用
// 注意:直接导入Log4j的类(使用Log4j自带的API)
import org.apache.log4j.Logger;public class MyClass {// 1. 获取Logger实例private static final Logger logger = Logger.getLogger(MyClass.class);public void doSomething() {// 2. 使用不同级别记录日志logger.debug("这是一个Debug信息,用于详细调试.");logger.info("业务逻辑正常执行的信息.");logger.warn("这是一个警告,表示潜在问题.");logger.error("这是一个错误,但应用还能运行.", new Exception("错误示例"));logger.fatal("这是一个致命错误,可能导致应用退出.");}
}

3.1.3 定位

Log4j是具体的日志实现,在这个时候还没有门面的概念,所以应用程序代码是直接依赖Log4j的API。

3.2 JUL(简单了解)

全名叫Java Util Logging,企业中应用很少,简单了解就行。

3.2.1 日志级别

和Log4j类似,名字有些不一样。
ALL→FINEST (类似TRACE)→FINER→FINE (类似DEBUG)→CONFIG→INFO→WARNING (类似WARN)→SEVERE (类似ERROR)
规则都是一样的。

3.2.2 使用方式

使用方式和log4j极为相似,也可以通过配置文件进行管理,但是配置就不如Log4j灵活了,所以应用很少,这里就不演示了。

3.2.3 定位

是JDK自带的日志实现。

3.3 JCL(简单了解)

全名叫Jakarta Commons Logging,这个也是第一个主流的日志门面
也就是说只依赖JCL的接口,JCL在运行时会通过类路径动态查找并绑定到具体的日志实现(就比如Log4j, JUL)

3.3.1 日志级别

日志级别基本上和log4j一样,这里就不重复罗列了。

3.3.2 使用方式

使用方式也很简单,就是导入依赖,然后直接在代码中引用。
1)导入依赖
<dependency><groupId>commons-logging</groupId><artifactId>commons-logging</artifactId><version>1.2</version>
</dependency>
2)代码中使用
// 注意:导入的是commons-logging的类
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;public class MyClass {// 获取Log实例private static final Log log = LogFactory.getLog(MyClass.class);public void doSomething() {// JCL的级别方法比较简单log.debug("Debug消息");log.info("Info消息");log.warn("Warn消息");log.error("Error消息");log.fatal("Fatal消息"); // 记录异常log.error("业务处理出错", new RuntimeException("异常"));}
}

3.4 SLF4J(⭐)

slf4j定位也是一个日志门面,并且是比JCL性能更好的门面。

3.3.1 日志级别

SLF4J的级别与Log4j基本一致:TRACE→DEBUG→INFO→WARN→ERROR

3.3.2 使用方式

单说slf4j的使用的话,门面的使用无非就是导入依赖,代码中引用,所以slf4j的使用演示我会放到后面和logback和log4j2这两个日志实现一块使用。

3.5 Logback-slf4j(⭐)

Logback是SLF4J的原生实现,是SLF4J的作者亲自设计,为了替代Log4j,性能更好,功能也更强(比如如自动热加载配置、更强大的Filter等)。
这边代码不再详细罗列,我会放到代码仓中,大家可以自行查看我主页的代码仓,或是直接访问这个链接:https://gitcode.com/m0_74977981/logDemo/tree/master/logsDemo
这里只说一点,logback自定义日志输出和log4j的语法不太一样,和log4j2倒是很相似。

3.6 Log4j2-slf4j(⭐)

Log4j2是对Log4j 1.x的彻底重写,它不仅是日志实现,也提供了自己的API。

3.6.1 日志级别

Log4j2的日志级别和slj4j/Logback一致:
TRACE→DEBUG→INFO→WARN→ERROR

3.6.2 使用方式

前面已经提到了,Log4j2提供了自己的API,所以这里理应是有两套使用方式的(使用自己原生的API以及使用其他门面),但是直接使用它原生的API会造成耦合,不推荐使用。
所以下面我将直接演示Log4j2-slf4j的使用。
使用很类似logback+slf4j:
1)配置文件
<?xml version="1.0" encoding="UTF-8"?>
<!--目标:- 使用 SLF4J API + Log4j2 实现- com.example.logsdemo.service1 -> logs/log1.log- com.example.logsdemo.service2 -> logs/log2.log
-->
<Configuration status="WARN"><Properties><Property name="LOG_DIR">logs</Property><Property name="LOG_PATTERN">%d{yyyy-MM-dd HH:mm:ss.SSS} %-5p [%t] %c{1.}.%M:%L - %m%ex{full}%n</Property></Properties><Appenders><Console name="Console" target="SYSTEM_OUT"><PatternLayout pattern="${LOG_PATTERN}"/></Console><!-- service1 独立文件 --><RollingFile name="Log1File"fileName="${LOG_DIR}/log1.log"filePattern="${LOG_DIR}/log1-%d{yyyy-MM-dd}-%i.log.gz"><PatternLayout pattern="${LOG_PATTERN}"/><Policies><TimeBasedTriggeringPolicy interval="1" modulate="true"/><SizeBasedTriggeringPolicy size="10MB"/></Policies><DefaultRolloverStrategy max="30"/></RollingFile><!-- service2 独立文件 --><RollingFile name="Log2File"fileName="${LOG_DIR}/log2.log"filePattern="${LOG_DIR}/log2-%d{yyyy-MM-dd}-%i.log.gz"><PatternLayout pattern="${LOG_PATTERN}"/><Policies><TimeBasedTriggeringPolicy interval="1" modulate="true"/><SizeBasedTriggeringPolicy size="10MB"/></Policies><DefaultRolloverStrategy max="30"/></RollingFile></Appenders><Loggers><!-- 精确匹配包,关闭向上继承,避免写入到 Root 的其他 Appender --><Logger name="com.example.logsdemo.service1" level="debug" additivity="false"><AppenderRef ref="Console"/><AppenderRef ref="Log1File"/></Logger><Logger name="com.example.logsdemo.service2" level="debug" additivity="false"><AppenderRef ref="Console"/><AppenderRef ref="Log2File"/></Logger><Root level="info"><AppenderRef ref="Console"/></Root></Loggers>
</Configuration>
如上配置,service1目录下的文件日志会输出到log1.log中,service2目录下的文件日志会输出到log2.log中。
2)代码中使用
可以看见:

今日份冷笑话

有一天,Java 程序员去咖啡店点单,
服务员问:“您喝什么?”
程序员答:“给我来一杯 Java。”
服务员愣了一下:“先生,我们这儿只有 爪哇 咖啡,没有 加瓦 咖啡。”
程序员叹了口气:“唉,原来你们还没升级到 JDK(咖啡开发工具包)……”
http://www.dtcms.com/a/560858.html

相关文章:

  • 第3章 变量与数据类型
  • pyside6 qt 事件循环
  • Secertpad搭建
  • 吞吐量、延迟、内存:深入理解垃圾回收的“三元悖论”
  • List接口和常用方法
  • 计算机一级考试网站怎么做用织梦系统做网站产权
  • Java 数据结构第二十八期:反射、枚举以及 lambda 表达式
  • Linux 磁盘分区与系统监控完全指南
  • 是普通网站地图好还是rss地图好一点网站建设申请费用
  • 使用Graphics2D创建滑块验证码
  • Flutter provide框架内部实现原理刨析
  • 关于rpm,yum,apt
  • 15.6.Bat脚本编写
  • 景德镇网站制作广告法
  • 可以做头像的网站网站区域名是什么
  • 新手记录使用uniapp-x开发鸿蒙应用
  • Linux+Apache+MySQL+PHP 架构下搭建 Discuz 社区论坛
  • 可替代Github Copilot的插件分享CodeGeeX
  • Ubuntu学习笔记
  • 双非大学生自学鸿蒙5.0零基础入门到项目实战 - 歌曲列表
  • 双非大学生自学鸿蒙5.0零基础入门到项目实战 -ArkTs核心
  • UVa 10989 Bomb Divide and Conquer
  • 【Linux】版本控制器Git和调试器—gdb/cgdb的使用
  • 怎么把个人做的网站上传到网上wordpress用户名钩子
  • 成都网站排名网站添加邮件发送怎么做
  • Spring AI 极简入门:15分钟集成AI到SpringBoot应用
  • 临潼城市建设局网站外资公司注册
  • 1.基础--数据库相关概念
  • 使用DTS迁移工具迁移oracle到DM
  • langchain agent的短期记忆