Java常见日志框架介绍及分析、Spring日志分析,Spring4和Spring5在日志的区别

目录

一.Java常用的日志框架介绍

二.Java常用日志框架分析

2.1 JUL使用

2.2Log4j使用

1.添加依赖

2.在classpath下面添加配置文件:log4j.properties

3.使用Log4j记录日志

2.3JCL使用分析

2.4SLF4J(酸辣粉4斤)

介绍(引用官网)

SLF4J绑定器

Spring4和Spring5的日志区别

Spring4的日志体系

Spring5的日志分析

小结:


日志作为项目系统记录关键节点信息的重要工具,相信大多数程序猿开发中都使用过不同类型的日志框架,而Java的日志框架五花八门,各有千秋,接下来就让我们慢慢来揭开这些花里胡哨的日志框架。

一.Java常用的日志框架介绍

  • JUL:(Java util logging )是位于java.util.logging包下面的一款日志框架,属于JDK自带的日志实现
  • Log4j:现在是Apache基金会下面的一个开源项目
  • Log4j2:Log4j的升级版,属于Apach基金会
  • JCL:(Jakarta Commons Logging)就是Apach的commons-logging.jar
  • SLF4J:(Simple Logging Facade for Java)有调侃的人取了个好听的别名(酸辣粉4斤),超级强大的一款日志框架

二.Java常用日志框架分析

2.1 JUL使用

使用很简单,可以看到在控制台输出了日志信息(记录到文件的操作需要自己写文件追加实现,这里不演示),需要注意的是看此时的Logger是java.util.logging.Logger

2.2Log4j使用

1.添加依赖

2.在classpath下面添加配置文件:log4j.properties

### 设置###
log4j.rootLogger = debug,stdout

### 输出信息到控制抬 ###
log4j.appender.stdout = org.apache.log4j.ConsoleAppender
log4j.appender.stdout.Target = System.out
log4j.appender.stdout.layout = org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern = [%-5p] %d{yyyy-MM-dd HH:mm:ss,SSS} method:%l%n%m%n

3.使用Log4j记录日志

我们发现JUL和Log4j都可以实现将日志输出到控制台(文件),姑且将这种类型称之为日志框架的实现者。

2.3JCL使用分析

1.引入JCL依赖,项目依赖如下:

<dependencies>
        <!--JCL-->
        <dependency>
            <groupId>commons-logging</groupId>
            <artifactId>commons-logging</artifactId>
            <version>1.2</version>
        </dependency>
        <!--Log4j-->
        <dependency>
            <groupId>log4j</groupId>
            <artifactId>log4j</artifactId>
            <version>1.2.17</version>
        </dependency>
    </dependencies>

使用JCL记录日志

好吧 怀疑是Log4j在捣鬼,那么我将Log4j依赖删除然后我们只引入JCL,不引入其他任何依赖

<dependencies>
        <!--JCL-->
        <dependency>
            <groupId>commons-logging</groupId>
            <artifactId>commons-logging</artifactId>
            <version>1.2</version>
        </dependency>
        <!--Log4j  注释掉你总不会还能打印Log4j的日志了吧-->
        <!--<dependency>
            <groupId>log4j</groupId>
            <artifactId>log4j</artifactId>
            <version>1.2.17</version>
        </dependency>-->
    </dependencies>

再跑起来试试

等等,为毛这段日志这么熟悉。。。这不就是前面的JUL的日志信息嘛,不过换了个马甲。难道JCL没有自己的实现,只是个日志的中间商?我们跟着源码去瞅一瞅究竟。

Log log = LogFactory.getLog("JCL");//点击getLog跟进去看看
//就是下面这一段
 public static Log getLog(String name) throws LogConfigurationException {
        return getFactory().getInstance(name);
    }
//再进去getInstance()
 public Log getInstance(String name) throws LogConfigurationException {
        Log instance = (Log) instances.get(name);
        if (instance == null) {
            instance = newInstance(name);
            instances.put(name, instance);
        }
        return instance;
    }
//再进去newInstance()
protected Log newInstance(String name) throws LogConfigurationException {
        Log instance;
        try {
            if (logConstructor == null) {
                instance = discoverLogImplementation(name);
            }
            else {
                Object params[] = { name };
                instance = (Log) logConstructor.newInstance(params);
            }

            if (logMethod != null) {
                Object params[] = { this };
                logMethod.invoke(instance, params);
            }

            return instance;
        } catch (LogConfigurationException lce) {
            throw lce;
        } catch (InvocationTargetException e) {
            Throwable c = e.getTargetException();
            throw new LogConfigurationException(c == null ? e : c);
        } catch (Throwable t) {
            throw new LogConfigurationException(t);
        }
    }

 

重点来了

在方法discoverLogImplementation内存在上面这么一段代码,像是在重复加载类,掀开classesToDiscover的盖头:

原来按照JCL按照自己定义的顺序去依次判定能否加载Log4j,JUL,加载成功则退出循环,返回找到的日志对象,JCL还真的是个中间商

给个图描绘一下JCL的思想

2.4SLF4J(酸辣粉4斤)

介绍(引用官网)

大致意思就是说酸辣粉是一款用于市面上各种日志框架的的一种抽象思像,借助于JCL的中间商原理,他比JCL更强大,可以适配几乎所有的日志实现,可以让用户更好的选择使用具体的日志框架。很重要的一点,就是建议用户在使用之前阅读一下使用手册

启用SLF4J只需要添加一个强制依赖slf4j-api

来吧,实战,去掉其他依赖,只加入slf4j-api

<dependencies>
        <!--JCL-->
        <!--<dependency>
            <groupId>commons-logging</groupId>
            <artifactId>commons-logging</artifactId>
            <version>1.2</version>
        </dependency>-->
        <!--Log4j  注释掉你总不会还能打印Log4j的日志了吧-->
        <!--<dependency>
            <groupId>log4j</groupId>
            <artifactId>log4j</artifactId>
            <version>1.2.17</version>
        </dependency>-->

        <!--SLF4J(酸辣粉4斤  多放辣椒)-->
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-api</artifactId>
            <version>1.7.25</version>
        </dependency>
    </dependencies>

  http://www.slf4j.org/codes.html#StaticLoggerBinder

官网的意思,大致是具体使用日志输出,还需要使用一个具体的日志的绑定器,绑定使用具体的日志框架。

SLF4J绑定器

SLF4J支持各种日志框架。 SLF4J发行版附带了几个称为“SLF4J绑定”的jar文件,每个绑定对应一个支持的框架

  • slf4j-log4j12:加入此依赖后SL4J将使用log4j1.2作为日志输出的具体实现
  • slf4j-jdk14:使用JDK1.4作为具体的日志实现
  • slf4j-jcl:使用JCL作为日志实现(再次用JCL选择实现。。。)
  • logback-classic(requires logback-core):使用logback作为具体的日志实现

来吧选择官方说的log4j的绑定器slf4j-log4j12

<!--SLF4J(酸辣粉4斤  多放辣椒)-->
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-api</artifactId>
            <version>1.7.25</version>
        </dependency>

        <!-- log4j1.2绑定器 -->
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-log4j12</artifactId>
            <version>1.7.25</version>
        </dependency>

果然,思想和JCL有点点类似,但是感觉酸辣粉更强大啊,扩展性更高。

Spring4和Spring5的日志区别

Spring4的日志体系

//引入Spring4  灭有其他任何依赖
<dependencies>
        <!-- https://mvnrepository.com/artifact/org.springframework/spring-context -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>4.3.8.RELEASE</version>
        </dependency>
    </dependencies>

进入方法查看日志是否是JUL

查看Spring4的依赖树:

结论:Spring4使用的是 JCL的日志体系

那么在Spring4下加入Log4j的依赖和配置文件,将使用Log4j记录日志。

Spring5的日志分析

新建一个Spring5项目

<dependencies>
        <!-- https://mvnrepository.com/artifact/org.springframework/spring-context -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>5.1.3.RELEASE</version>
        </dependency>
    </dependencies>

无日志输出,同样 查看Sping5的依赖树

发现仍然是JCL框架,不过名字被修改成了spring-jcl,猜想是Spring自己改造后的jcl,进入类AbstractApplicationContext查看Logger的实例化

进入工厂方法LogFactory.getLog()

 //1.LogFactory.getLog(Class clazz)
public static Log getLog(Class<?> clazz) {
        return getLog(clazz.getName());
    }
//2.getLog(String name)
public static Log getLog(String name) {
        return LogAdapter.createLog(name);
    }
//3.点击LogAdapter.createLog

public static Log createLog(String name) {
        switch(logApi) {
        case LOG4J:
            return LogAdapter.Log4jAdapter.createLog(name);
        case SLF4J_LAL:
            return LogAdapter.Slf4jAdapter.createLocationAwareLog(name);
        case SLF4J:
            return LogAdapter.Slf4jAdapter.createLog(name);
        default:
            return LogAdapter.JavaUtilAdapter.createLog(name);
        }
    }
//4.查看logApi何时赋值 ----静态构造块中
static {
        logApi = LogAdapter.LogApi.JUL;
        ClassLoader cl = LogAdapter.class.getClassLoader();

        try {
            Class.forName("org.apache.logging.log4j.spi.ExtendedLogger", false, cl);
            logApi = LogAdapter.LogApi.LOG4J;
        } catch (ClassNotFoundException var6) {
            try {
                Class.forName("org.slf4j.spi.LocationAwareLogger", false, cl);
                logApi = LogAdapter.LogApi.SLF4J_LAL;
            } catch (ClassNotFoundException var5) {
                try {
                    Class.forName("org.slf4j.Logger", false, cl);
                    logApi = LogAdapter.LogApi.SLF4J;
                } catch (ClassNotFoundException var4) {
                    ;
                }
            }
        }

    }

直接赋值仍然是java.util.logging,然后尝试加载Log4j2,若能正常加载那么就是Log4j2,然后加载酸辣粉

引入Log4j2的依赖

 <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>5.1.3.RELEASE</version>
        </dependency>

        <!-- log4j2 -->
        <dependency>
            <groupId>org.apache.logging.log4j</groupId>
            <artifactId>log4j-core</artifactId>
            <version>2.11.1</version>
        </dependency>

只是说缺少了Log4j2的配置文件

弄个Log4j2的配置文件

<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="ERROR">
    <Appenders>
        <Console name="Console" target="SYSTEM_OUT">
            <PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n" />
        </Console>
    </Appenders>

    <Loggers>
        <Root level="DEBUG">
            <AppenderRef ref="Console" />
        </Root>
    </Loggers>
</Configuration>

小结:

SLF4J的出现带来了许多灵活可配的日志方案,比如主流的slf4j+logback的日志记录方案,当我们在使用spring时,又想使用其他的日志方案,则需要将spring依赖的jcl排除

<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-core</artifactId>
    <exclusions>
        <exclusion>
            <groupId>commons-logging</groupId>
            <artifactId>commons-logging</artifactId>
        </exclusion>
    </exclusions>
    <version>${springframework.version}</version>
</dependency>

如果有多个组件依赖了jcl,则需要各个剔除,操作比较复杂

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值