玩转杂乱无章的java日志体系

一、总体介绍

目前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

目前的日志框架有 jdk 自带的 logging,log4j1、log4j2、logback ,这些框架都自己定制了日志 API ,并且有相应的实现。还有jcl(Jakarta Commons Logging)和slf4j,这两个是面向接口的,没有具体实现,是日志里的门面,这两个与上面四个日志框架的关系如下:

jcl:

玩转杂乱无章的java日志体系_第1张图片

从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---------------");
	}
}

运行结果可以看出采用的是jdk loggin,这正印证了我们所说的找不到log4j后接着就是找jdk:

玩转杂乱无章的java日志体系_第2张图片

如果我们追加log4j的jar包进去:


			log4j
			log4j
			1.2.16
		


玩转杂乱无章的java日志体系_第3张图片


slf4j:

slf4j的实现上则不一样,先来看他们的关系图:

玩转杂乱无章的java日志体系_第4张图片


Slf4j它是通过中间集合jar包去桥接他们的实现。


二、相关运用

引出问题:如果项目中旧模块使用的是log4j来打印日志的话,而新模块想用logback来统一打印日志的话,那么这时该怎么办呢?

难不成让他们输出两个日志文件呀,那样太乱了,那也不能去改旧模块代码吧,这太耗时了,最佳方案可以这么做:去掉log4j包引入log4j-over-slf4j包(这个包使之前代码使用log4j不会因为找不到而报错)和slf4j-api,以及logback-core和logback-classic(将slf4j桥接到logback),意思是让log4j交给slf4j,然后让slf4j桥接到logback,如下图所示:

玩转杂乱无章的java日志体系_第5张图片

所需要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---------------");
	}
}
打印结果可以看出,日志输出一致:

玩转杂乱无章的java日志体系_第6张图片
同理如果实现从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---------------");
	}
}



打印结果可以看出,日志输出一致:
玩转杂乱无章的java日志体系_第7张图片


三、jcl的log4j实现切换为log4j2

原理如下图:

玩转杂乱无章的java日志体系_第8张图片



说明:将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---------------");
	}
}




	
		
			
		
	
	
		
             
             
             
             
         
	


运行结果可以看出日志打印以及统一为log4j2:



以上纯属个人绵薄认识,如有不对地方望指正

你可能感兴趣的:(java日志体系)