Java-Java日志体系-《Java笔记》

admin 2025-10-19 03:28:45 编程 来源:ZONE.CI 全球网 0 阅读模式

Java 日志

Log日志体系

在日常工作中可能看到项目中依赖的跟日志相关的jar包有很多,commons-logging.jar、log4j.jar、sl4j-api.jar、logback.jar等等,眼花缭乱。要正确的配置,使得jar包相互作用生效之前,就先要理清它们之间的关系。

背景/发展史

那就要从Java Log的发展历程开始说起。

  1. log4j(作者Ceki Gülcü)出来时就等到了广泛的应用(注意这里是直接使用),是Java日志事实上的标准,并成为了Apache的项目
  2. Apache要求把log4j并入到JDK,SUN拒绝,并在jdk1.4版本后增加了JUL(java.util.logging)
  3. 毕竟是JDK自带的,JUL也有很多人用。同时还有其他日志组件,如SimpleLog等。这时如果有人想换成其他日志组件,如log4j换成JUL,因为api完全不同,就需要改动代码。
  4. Apache见此,开发了JCL(Jakarta Commons Logging),即commons-logging-xx.jar。它只提供一套通用的日志接口api,并不提供日志的实现。很好的设计原则嘛,依赖抽象而非实现。这样应用程序可以在运行时选择自己想要的日志实现组件。
  5. 这样看上去也挺美好的,但是log4j的作者觉得JCL不好用,自己开发出slf4j,它跟JCL类似,本身不替供日志具体实现,只对外提供接口或门面。目的就是为了替代JCL。同时,还开发出logback,一个比log4j拥有更高性能的组件,目的是为了替代log4j。
  6. Apache参考了logback,并做了一系列优化,推出了log4j2

    关系/依赖

    大概了解心路历程后,再详细看看它们之间的关系、依赖。

    JCL

    commons-logging已经停止更新,最后的状态如下所示:Java日志体系 - 图1JCL支持日志组件不多,不过也有很人用的,例如Spring现在用的也越来越少了,也不多讲了

    SLF4J

    因为当时Java的日志组件比较混乱繁杂,Ceki Gülcü推出slf4j后,也相应为行业中各个主流日志组件推出了slf4j的适配图的意思为如果想用slf4j作为日志门面的话,如何去配合使用其他日志实现组件,这里说明一下(注意jar包名缺少了版本号,在找版本时也要注意版本之间是否兼容)
  • slf4j%20+%20logbackslf4j-api.jar%20+%20logback-classic.jar%20+%20logback-core.jar
  • slf4j%20+%20log4jslf4j-api.jar%20+%20slf4j-log4j12.jar%20+%20log4j.jar
  • slf4j%20+%20julslf4j-api.jar%20+%20slf4j-jdk14.jar
  • 也可以只用slf4j无日志实现slf4j-api.jar%20+%20slf4j-nop.jar

    SLF4J的适配

    slf4j支持各种适配,无论现在是用哪种日志组件,都可以通过slf4j的适配器来使用上slf4j。只要切换到了slf4j,那么再通过slf4j用上实现组件,即上面说的。其实总的来说,无非就是以下几种情况

  • 在用JCL使用jcl-over-slf4j.jar适配

  • 在用log4j使用log4j-over-slf4j.jar适配
  • 在用JUL使用jul-to-slf4j.jar适配

一个整体的依赖图

让Spring统一输出

这就是为了对slf4j的适配做一个例子说明。Spring是用JCL作为日志门面的,项目中是slf4j + logback,怎么让Spring也用到logback作为日志输出呢?这样的好处就是可以统一项目内的其他模块、框架的日志输出(日志格式,日志文件,存放路径等,以及其他slf4j支持的功能)很简单,就是加入jcl-over-slf4j.jar就好了。Java日志体系 - 图5

适配思路

其实很简单

  1. 首先确认需要统一日志的模块、框架是使用哪个日志组件的,然后再找到sfl4j的适配器。
  2. 记得去掉无用的日志实现组件,只保留要用的。

    常见问题

    slf4j的日志加载会在程序启动时把日志打出来,所以一定要注意,它会说明加载是否成功,加载了那个日志实现。slf4j已经对错误作了说明:http://www.slf4j.org/codes.html下面讲一下可能经常遇到的问题

    Failed to load class org.slf4j.impl.StaticLoggerBinder

    没找到日志实现,如果已经写上了对应的日志实现依赖了,要检查一下了,一般来说极有可能是版本不兼容。

    Multiple bindings

    找到多个日志实现,slf4j会找其中一个作为日志实现。

    代码规范

    阿里对此的代码规范:【强制】应用中不可直接使用日志系统(Log4j、Logback)中的 API,而应依赖使用日志框架 SLF4J 中的 API,使用门面模式的日志框架,有利于维护和各个类的日志处理方式统一。
    1. import org.slf4j.Logger;
    2. import org.slf4j.LoggerFactory;
    3. private static final Logger logger = LoggerFactory.getLogger(Abc.class);
以太坊cppgolang区别 编程

以太坊cppgolang区别

以太坊是一种去中心化的开源平台,它采用智能合约技术,旨在构建和运行不受干扰的分布式应用程序。作为目前最受欢迎的区块链平台之一,以太坊提供了多种编程语言的支持,其
progolang 编程

progolang

Go语言(Golang)是由Google开发的一门静态类型编程语言。作为一名专业的Golang开发者,我深知这门语言的优势和特点。在本文中,我将介绍Golang
golangn个发送者 编程

golangn个发送者

Golang是一种开源的编程语言,由Google团队开发,旨在提高程序的并发性和简化软件开发过程。在Go语言中,有时需要向多个接收者发送信息。本文将介绍如何在G
golang技能图谱 编程

golang技能图谱

从互联网行业的快速发展到人工智能技术的日益成熟,各种编程语言也应运而生。而在这众多的编程语言中,Golang(即Go)作为一门强大且高效的开发语言备受关注。Go
评论:0   参与:  9