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

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/u011320740/article/details/78923994

一、总体介绍

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


从jcl源码中可以看出,jcl有4个四个选择:jdk13,jdk14,log4j,simpleLog,jcl加载时按照顺序log4j>jdk13>jdk14> simpleLog依次加载,如果查找到log4j包则使用log4j,如果没有依次类推。

我们可以写个例子来验证下这点:

<dependency>
		    <groupId>commons-logging</groupId>
		    <artifactId>commons-logging</artifactId>
		    <version>1.2</version>
		</dependency>


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:



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

<dependency>
			<groupId>log4j</groupId>
			<artifactId>log4j</artifactId>
			<version>1.2.16</version>
		</dependency>




slf4j:

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集成包

代码测试:

<dependency>
		    <groupId>org.slf4j</groupId>
		    <artifactId>slf4j-api</artifactId>
		    <version>1.7.25</version>
		</dependency>
		<!-- <dependency>
			<groupId>log4j</groupId>
			<artifactId>log4j</artifactId>
			<version>1.2.16</version>
		</dependency> -->
		<dependency>
			<groupId>org.slf4j</groupId>
			<artifactId>log4j-over-slf4j</artifactId>
			<version>1.7.13</version>
		</dependency>
		<dependency>
			<groupId>ch.qos.logback</groupId>
			<artifactId>logback-core</artifactId>
			<version>1.1.3</version>
		</dependency>
		<dependency>
			<groupId>ch.qos.logback</groupId>
			<artifactId>logback-classic</artifactId>
			<version>1.1.3</version>
		</dependency>


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集成包

代码测试:
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>com.cwh.javaLog</groupId>
  <artifactId>javaLog</artifactId>
  <version>0.0.1-SNAPSHOT</version>
  <dependencies>
		<dependency>
		    <groupId>org.slf4j</groupId>
		    <artifactId>slf4j-api</artifactId>
		    <version>1.7.25</version>
		</dependency>
		<dependency>
		    <groupId>org.slf4j</groupId>
		    <artifactId>jul-to-slf4j</artifactId>
		    <version>1.7.25</version>
		</dependency>
		<dependency>
			<groupId>log4j</groupId>
			<artifactId>log4j</artifactId>
			<version>1.2.16</version>
		</dependency>
		<dependency>
		    <groupId>org.slf4j</groupId>
		    <artifactId>slf4j-log4j12</artifactId>
		    <version>1.7.25</version>
		</dependency>
  </dependencies>
  <build/>
</project>


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集成包

测试代码:

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>com.cwh.javaLog</groupId>
  <artifactId>javaLog</artifactId>
  <version>0.0.1-SNAPSHOT</version>
  <dependencies>
		<dependency>
		    <groupId>org.slf4j</groupId>
		    <artifactId>slf4j-api</artifactId>
		    <version>1.7.25</version>
		</dependency>
		<!-- https://mvnrepository.com/artifact/commons-logging/commons-logging -->
		<!-- <dependency>
		    <groupId>commons-logging</groupId>
		    <artifactId>commons-logging</artifactId>
		    <version>1.2</version>
		</dependency>
		<dependency>
			<groupId>log4j</groupId>
			<artifactId>log4j</artifactId>
			<version>1.2.16</version>
		</dependency> -->
		<!-- https://mvnrepository.com/artifact/org.apache.logging.log4j/log4j-api -->
		<dependency>
		    <groupId>org.apache.logging.log4j</groupId>
		    <artifactId>log4j-api</artifactId>
		    <version>2.9.1</version>
		</dependency>
		<!-- https://mvnrepository.com/artifact/org.apache.logging.log4j/log4j-core -->
		<dependency>
		    <groupId>org.apache.logging.log4j</groupId>
		    <artifactId>log4j-core</artifactId>
		    <version>2.9.1</version>
		</dependency>
		<!-- https://mvnrepository.com/artifact/org.apache.logging.log4j/log4j-slf4j-impl -->
		<dependency>
		    <groupId>org.apache.logging.log4j</groupId>
		    <artifactId>log4j-slf4j-impl</artifactId>
		    <version>2.9.1</version>
		</dependency>
		<!-- https://mvnrepository.com/artifact/org.slf4j/jcl-over-slf4j -->
		<dependency>
		    <groupId>org.slf4j</groupId>
		    <artifactId>jcl-over-slf4j</artifactId>
		    <version>1.7.25</version>
		</dependency>
		
  </dependencies>
  <build/>
</project>

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


<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="WARN">
	<Appenders>
		<Console name="Console" target="SYSTEM_OUT">
			<PatternLayout pattern="%d{yyyy/MM/dd HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n" />
		</Console>
	</Appenders>
	<Loggers>
		<root level="all">
             <appender-ref ref="Console"/>
             <appender-ref ref="RollingFileInfo"/>
             <appender-ref ref="RollingFileWarn"/>
             <appender-ref ref="RollingFileError"/>
         </root>
	</Loggers>
</Configuration>


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



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

猜你喜欢

转载自blog.csdn.net/u011320740/article/details/78923994