1. System.out
1.1. DK1.3及以前,2001年以前,Java是没有日志库的,打印日志全凭System.out和System.err
1.2. 缺点:
- 产生大量的IO操作 同时在生产环境中 无法合理的控制是否需要输出
- 输出的内容不能保存到文件
- 只打印在控制台,打印完就过去了,也就是说除非你一直盯着程序跑
- 无法定制化,且日志粒度不够细
2. log4j
2.1. 介绍
2001年,一个叫Ceki Gülcü的大佬搞了一个日志库log4j,后来Log4j成为Apache项目,Ceki也加入Apache组织Apache还曾经建议Sun引入Log4j到Java的标准库中,但Sun拒绝了
Apache 的一个开放源代码项目,通过使用Log4j,我们可以控制日志信息输送的目的地是控制台、文件、GUI组件、甚至是套接口服务器、NT的事件记录器、UNIX Syslog守护进程等;用户也可以控制每一条日志的输出格式;通过定义每一条日志信息的级别,用户能够更加细致地控制日志的生成过程。这些可以通过一个配置文件来灵活地进行配置,而不需要修改程序代码。
在JDK 1.3及以前,Java打日志依赖System.out.println(), System.err.println()或者e.printStackTrace(),Debug日志被写到STDOUT流,错误日志被写到STDERR流。这样打日志有一个非常大的缺陷,即无法定制化,且日志粒度不够细。log4j是在这样的环境下诞生的,它是一个里程碑式的框架,它定义的Logger、Appender、Level等概念如今已经被广泛使用
随着用户体量的提升,Log4j无法满足高性能的要求,成为应用的性能瓶颈
2.2. 依赖
在https://mvnrepository.com/中可以查到,log4j1从2005年11月更新到2012年3月,后面就没再更新了 最新的依赖(May 26, 2012)
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</dependency>
2015年8月5日,项目管理委员会宣布Log4j 1.x已达到使用寿命。建议用户使用Log4j 1升级到Apache Log4j2
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<exclusions>
<exclusion>
<artifactId>logback-classic</artifactId>
<groupId>ch.qos.logback</groupId>
</exclusion>
<exclusion>
<artifactId>log4j-over-slf4j</artifactId>
<groupId>org.slf4j</groupId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
</dependency>
3. JUL
Sun有自己的小心思,2002年2月JDK1.4发布,Sun推出了自己的日志标准库JUL(Java Util Logging),其实是照着Log4j抄的,而且还没抄好,还是在JDK1.5以后性能和可用性才有所提升。
由于Log4j比JUL好用,并且成熟,所以Log4j在选择上占据了一定的优势。
4. JCL
4.1. 介绍
2002年8月Apache推出了JCL(Jakarta Commons Logging),也就是日志抽象层,支持运行时动态加载日志组件的实现,当然也提供一个默认实现Simple Log(在ClassLoader中进行查找,如果能找到Log4j 则默认使用log4j实现,如果没有则使用JUL 实现,再没有则使用JCL内部提供的Simple Log实现
4.2. 缺点
- 效率较低
- 容易引发混乱
- 使用了自定义ClassLoader的程序中,使用JCL会引发内存泄露
4.3. 依赖
不过现在Apache Commons Logging也不更新了,最新的依赖(Jul 05, 2014)
<dependency>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
<version>1.2</version>
</dependency>
5. Slf4j
5.1. 简介
2006年巨佬Ceki(Log4j的作者)因为一些原因离开了Apache组织,之后Ceki觉得JCL不好用,自己一套新的日志标准接口规范Slf4j(Simple Logging Facade for Java),也可以称为日志门面,很明显Slf4j是对标JCL,后面也证明了Slf4j比JCL更优秀。
巨佬Ceki提供了一系列的桥接包来帮助Slf4j接口与其他日志库建立关系,这种方式称为桥接设计模式。
代码使用Slf4j接口,就可以实现日志的统一标准化,后续如果想要更换日志实现,只需要引入Slf4j与相关的桥接包,再引入具体的日志标准库即可。
5.2. 日志打印
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class HelloWorld {
public static void main(String[] args) {
Logger logger = LoggerFactory.getLogger(HelloWorld.class);
logger.info("Hello World[{}]",”站位符打印”);
}
}
5.3. 日志桥接
5.4. 所有日志到slf4j
1、将系统中其他日志框架先排除出去;
2、用中间包来替换原有的日志框架;
3、我们导入slf4j其他的实现