前言
日志应该是除了代码之外,程序员最好的朋友了,它可以帮助我们定位问题、修复bug,或者是确认服务是否正常运转;很多时候我们做一次部署只是为了加几行日志;
而 Tomcat 作为经久畅销的web 服务器,一直是web 开发者首选,而 Tomcat 的原生日志是我们判断这个服务器是否正常运转的重要数据。
Java 日志组件
这里我们按照历史顺序简单介绍一下 Java 常用的日志组件,
JUL(Java Util Logging): 是 jdk 自带的log 实现组件,虽然是官方出品但是它并没有被广泛使用,主要是下面几个原因
“1. JUL 出现的太晚了,2002年它才被放到 jdk1.4 中,当时已经有很多第三方的日志组件被广泛使用了
JUL早期性能问题太明显,到JDK1.5才有所改善,但是它和其他第三方日志组件logback或log4j2相比也还是有差距JUL提供的功能不如第三方组件logback或log4j2完善
log4j 是在 logback 之前被广泛使用的日志实现组件,log4j 在设计上十分优秀,对后期的Java 日志框架有深远的影响,但是它在性能上存在缺陷;logback 出现之后就取代了 log4j
JCL(Apache Commons Logging): apache 提出的 Log Facade,只提供日志api,不提供实现,通过不同的 Adapter 来使用 JUL 或者 log4j;在打印日志的时候调用的都是 JCL 指定的api ,具体实现是看当前的 classpath 中有什么实现,如果什么都没有
slf4j(The Simple Logging Facade For Java): slf4j 是 Ceki Gülcü 开发的 Log Facade,主要是因为Ceki Gülcü 觉得作为日志统一接口的 JCL 设计的不合理:
下面这种写法不管是否输出 debug 级别的时候都需要做一次字符串拼接,如果这种代码被反复调用就会产生很多无用的字符串拼接,影响性能。
1 | logger.debug("log:" + log); |
而官方给出的最佳时间方式是这样的:
1 | if (logger.isDebugEnabled()) { |
怎么看都是反人类的设计,所以在 slf4j 中,设计的api 是这样的1
logger.debug("log:{}", log);
logback: logback 也是Ceki Gülcü 开发的日志实现,在 log4j 的基础上进行了改进,提供了更好的性能实现,异步logger,Filter 等更能多的特性。
Ceki Gülcü 给我们开发了很好用的日志组件,但是现在有了两个 Log Facade 和三个流行的 Log Implementation,事情变的复杂了;Ceki Gülcü 作为一个完美主义者,为了我们能在不同的log 之间自由切换,他又开发了各种 Adapater 和 Bridge 来连接,这里盗用一张 slf4j 官网的图片

log4j2: log4j2 的开发维护人员不想看着 log4j 被 slf4j/logback 所取代,在设计上很大程度的模仿了 slf4j/logback,完全脱离log4j1.x,在性能上实现了很大的提升,作为一个高仿品这里不多介绍。
Tomcat 的日志实现方法
Tomcat 内部整合的日志模块是 JULI,JULI是从 JCL fork 过来的一个重命名分支,默认被硬编码使用 JUL 作为日志实现,从而保证 Tomcat 本身的日志和业务日志实现完美隔离。
而Tomcat的日志的配置文件默认位置是 ${catalina.base}/conf/logging.properties,如果无法读取或不存在的时候,就会去找${java.home}/lib/logging.properties;在web应用的范围内也有一个日志配置文件 WEB-INF/classes/logging.properties
1 | # Licensed to the Apache Software Foundation (ASF) under one or more |