一、总体介绍
目前java日志框架有以下几种:
日志框架 |
描述 |
相关jar |
Jdk logging |
jdk 自带的 |
slf4j-jdk14、jul-to-slf4j |
log4j |
Apache 的一个开放源代码项目 |
log4j、slf4j-log4j12、log4j-over-slf4j |
log4j2 |
Log4j的加强版 |
log4j-api、log4j-core、log4j-slf4j-impl |
logback |
Logback 是由 log4j 创始人设计的又一个开源日记组件 |
logback-core、logback-classic |
Jcl |
commons-logging是Apache commons类库中的一员、能够选择使用Log4j还是JDK Logging,但是他不依赖Log4j,JDK Logging的API |
commons-logging、slf4j-jcl 、jcl-over-slf4j |
jcl:
从jcl源码中可以看出,jcl有4个四个选择:jdk13,jdk14,log4j,simpleLog,jcl加载时按照顺序log4j>jdk13>jdk14> simpleLog依次加载,如果查找到log4j包则使用log4j,如果没有依次类推。
我们可以写个例子来验证下这点:
commons-logging
commons-logging
1.2
package javaLog;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
public class LogTest {
static Log jcl = LogFactory.getLog(LogTest.class);
public static void main(String[] args) {
jcl.info("jcl---------------hello---------------");
}
}
如果我们追加log4j的jar包进去:
log4j
log4j
1.2.16
slf4j:
Slf4j它是通过中间集合jar包去桥接他们的实现。
二、相关运用
引出问题:如果项目中旧模块使用的是log4j来打印日志的话,而新模块想用logback来统一打印日志的话,那么这时该怎么办呢?
难不成让他们输出两个日志文件呀,那样太乱了,那也不能去改旧模块代码吧,这太耗时了,最佳方案可以这么做:去掉log4j包引入log4j-over-slf4j包(这个包使之前代码使用log4j不会因为找不到而报错)和slf4j-api,以及logback-core和logback-classic(将slf4j桥接到logback),意思是让log4j交给slf4j,然后让slf4j桥接到logback,如下图所示:
所需要jar包:
log4j-over-slf4j | 实现log4j1切换到slf4j |
slf4j-api | slf4j所需jar |
logback-core | logback核心包 |
logback-classic | slf4j与logback集成包 |
代码测试:
org.slf4j
slf4j-api
1.7.25
org.slf4j
log4j-over-slf4j
1.7.13
ch.qos.logback
logback-core
1.1.3
ch.qos.logback
logback-classic
1.1.3
package javaLog;
import org.apache.log4j.Logger;
public class LogTest {
static Logger log4j = Logger.getLogger(LogTest.class);
static org.slf4j.Logger logback = org.slf4j.LoggerFactory.getLogger(LogTest.class);
public static void main(String[] args) {
log4j.info("log4j---------------hello---------------");
logback.info("logback---------------hello---------------");
}
}
打印结果可以看出,日志输出一致:
同理如果实现从jdk loggin切换到log4j呢,和上面差不多
所需jar包
jul-to-slf4j | 实现jdk-logging切换到slf4j |
slf4j-api | slf4j所需jar |
log4j | log4j所需包 |
slf4j-log4j12 | slf4j与log4j集成包 |
4.0.0
com.cwh.javaLog
javaLog
0.0.1-SNAPSHOT
org.slf4j
slf4j-api
1.7.25
org.slf4j
jul-to-slf4j
1.7.25
log4j
log4j
1.2.16
org.slf4j
slf4j-log4j12
1.7.25
package javaLog;
import java.util.logging.Logger;
import org.slf4j.bridge.SLF4JBridgeHandler;
public class LogTest {
static{
SLF4JBridgeHandler.install();
}
static Logger jul = Logger.getLogger(LogTest.class.getName());
static org.slf4j.Logger log4j = org.slf4j.LoggerFactory.getLogger(LogTest.class);
public static void main(String[] args) {
jul.info("jul---------------hello---------------");
log4j.info("log4j---------------hello---------------");
}
}
三、jcl的log4j实现切换为log4j2
原理如下图:
说明:将jcl适配给slf4j,然后slf4j桥接到log4j2
所需jar包:
jcl-over-slf4j | jcl适配slf4j集成包 |
slf4j-api | slf4j所需 |
log4j-api | log4j2接口 |
log4j-core | log4j核心实现 |
log4j-slf4j-impl | log4j与slf4j集成包 |
测试代码:
4.0.0
com.cwh.javaLog
javaLog
0.0.1-SNAPSHOT
org.slf4j
slf4j-api
1.7.25
org.apache.logging.log4j
log4j-api
2.9.1
org.apache.logging.log4j
log4j-core
2.9.1
org.apache.logging.log4j
log4j-slf4j-impl
2.9.1
org.slf4j
jcl-over-slf4j
1.7.25
package javaLog;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class LogTest {
static Log jcl = LogFactory.getLog(LogTest.class);
static Logger log4j2 = LoggerFactory.getLogger(LogTest.class);
public static void main(String[] args) {
jcl.info("jcl---------------hello---------------");
log4j2.info("log4j2---------------hello---------------");
}
}
以上纯属个人绵薄认识,如有不对地方望指正