Java日志体系(四) JCL日志详解,示例,依赖选择,默认依赖顺序,源码分析 |8月更文挑战

191 阅读3分钟

这是我参与8月更文挑战的第13天,活动详情查看:8月更文挑战

简介

JCL,全称为"Jakarta Commons Logging",也可称为"Apache Commons Logging"。

JCL是Apache提供的日志框架,门面日志。采用适配器模式,提供统一的对外接口,底层委托给具体的日志框架,如log4j,Jul,simplelog等

官方网址

commons.apache.org/proper/comm…

学习手册

commons.apache.org/proper/comm…

示例

创建maven工程,依然使用前面使用的maven做测试。

添加JCL依赖 即common-log

<!--JCL日志框架-->
<dependency>
     <groupId>commons-logging</groupId>
     <artifactId>commons-logging</artifactId>
     <version>1.2</version>
 </dependency>

测试类(使用JUL依赖)

public class JCLTest {
    Log log = LogFactory.getLog(JCLTest.class);
    @Test
    public void test() {
        log.debug("Debug info.");
        log.info("Info info");
        log.warn("Warn info");
        log.error("Error info");
        log.fatal("Fatal info");
    }
}

输出:(依赖jul) JUL默认的日志级别为INFO 所以Debug info 不会被输出。

三月 18, 2021 10:26:38 下午 cn.ling.logs.JCLTest test
信息: Info info
三月 18, 2021 10:26:38 下午 cn.ling.logs.JCLTest test
警告: Warn info
三月 18, 2021 10:26:38 下午 cn.ling.logs.JCLTest test
严重: Error info
三月 18, 2021 10:26:38 下午 cn.ling.logs.JCLTest test
严重: Fatal info

Process finished with exit code 0

上面示例先不说是common-log如何找到JUL依赖。下面我们切换到Log4j依赖看一下结果。

使用log4j依赖输出日志

添加log4j依赖

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

log4j.properties配置

# 日志输出级别DEBUG 输出目的地 FILE CONSOLE
log4j.rootLogger = DEBUG, FILE, CONSOLE

#将日志信息输出到对应的磁盘文件中
log4j.appender.FILE=org.apache.log4j.FileAppender
#将日志输出到D盘的logs/log.out文件中
log4j.appender.FILE.File=D:/logs/log.out
#请求的日志消息被立即输出,默认为true
log4j.appender.FILE.ImmediateFlush=true
#指定日志输出的最低级别,默认为DEBUG;如果日志请求的级别低于此级别,则不会输出此请求日志信息
log4j.appender.FILE.Threshold = DEBUG
#将新增日志追加到文件中,默认为true为不覆盖,false为覆盖
log4j.appender.FILE.Append=true
log4j.appender.FILE.layout=org.apache.log4j.PatternLayout
log4j.appender.FILE.layout.conversionPattern=Log4j  %d{ABSOLUTE} %5p %c{1}:%L - %m%n

log4j.appender.CONSOLE=org.apache.log4j.ConsoleAppender
log4j.appender.CONSOLE.Target=System.out
log4j.appender.CONSOLE.ImmediateFlush=true
log4j.appender.CONSOLE.Threshold = DEBUG
log4j.appender.CONSOLE.layout=org.apache.log4j.PatternLayout
log4j.appender.CONSOLE.encoding=UTF-8
log4j.appender.CONSOLE.layout.conversionPattern=Log4j %d{ABSOLUTE} %5p %c{1}:%L - %m%n

执行测试类输出

console控制台输出

Log4j 22:33:12,313 DEBUG JCLTest:16 - Debug info.
Log4j 22:33:12,313  INFO JCLTest:17 - Info info
Log4j 22:33:12,313  WARN JCLTest:18 - Warn info
Log4j 22:33:12,313 ERROR JCLTest:19 - Error info
Log4j 22:33:12,313 FATAL JCLTest:20 - Fatal info

Process finished with exit code 0

文件输出: 在这里插入图片描述

common-log原理解析

Log log = LogFactory.getLog(JCLTest.class);

idea中选中Log 按快捷键Ctrl+H 查看Log的实现类。 在这里插入图片描述 LogFactory的实现类 在这里插入图片描述

通过debug 观察一下

在这里插入图片描述在这里插入图片描述在这里插入图片描述 getFactory方法给我们一个默认的实现类LogFactoryImpl 在这里插入图片描述 在这里插入图片描述 在这里插入图片描述 到此才真正完成一个实例。 discoverLogImplementation方法中如下图所示的位置,我们看到common-log实现类的顺序。 在这里插入图片描述

common-log同时存在log4j依赖和JUL依赖如何选择

==注意:在没有特别的配置时,上面示例已经给出了结果,同时存在log4j依赖和JUL依赖,common-log会选择log4j。优先顺序参见上图。==

时存在log4j和JUL 要用JUL怎么处理? 通过commons-logging.properties配置

commons-logging.properties

# JCL依赖log4j
#org.apache.commons.logging.Log = org.apache.commons.logging.impl.Log4JLogger

# JCL依赖JUL
org.apache.commons.logging.Log = org.apache.commons.logging.impl.Jdk14Logger

使用commons-logging.properties配置依赖JUL

输出结果: 在这里插入图片描述

使用commons-logging.properties配置依赖Log4j

修改配置文件如下: 在这里插入图片描述

输出结果: 在这里插入图片描述