Log4j2的使用,以及Spring 和 SpringBoot 分别使用Slf4j集成Log4j2构建项目日志系统

一、日志框架介绍

        Slf4j(全称是Simple Loging Facade For Java) 是一个为Java程序提供日志输出的统一接口,是对所有日志框架制定的一种规范、标准、接口,并不是一个具体的日志实现方案,因此Slf4j并不能但单独使用,需要和其他具体的日志框架实现配合使用,比如log4j、logback、log4j2等。

        Log4j2是Log4j 1.x和Logback的改进版,它相比其前身Log4j 1.x进行了重大改进,并提供了Logback中可用的许多改进,吸取了优秀的Logback的设计而重新推出的一款新组件,同时修复了Logback架构中的一些固有问题。 从GitHub的更新日志来看,Logback更新活跃度一般,而作为知名组织的Apache下的Log4j2的更新却是非常活跃的,并且流行度也很高,Log4j 1.x 于2015年8月停止维护更新了。

       Log4j2官方网址:http://logging.apache.org/log4j/2.x/

二、为什么需要用Slf4j接口集成Log4j2,而不直接使用其具体实现的Log4j2

        Slf4j接口是一个为Java程序提供日志输出的统一接口,是对所有日志框架制定的一种规范、标准、接口,可以有多个实现,使用时是面向接口的 (导入的包都是slf4j的包而不是具体某个日志框架中的包),即直接和接口交互,不直接使用具体实现,所以可以任意的更换具体实现而不用更改代码中的日志相关代码,这就可以很好的保证我们的日志系统具有良好的兼容性,能够兼容当前常见的几种日志系统,同时使用log4j2而不是log4j是因为Log4j 1.x 在高并发情况下出现死锁导致cpu使用率异常飙升,而Log4j2.0基于LMAX Disruptor的异步日志在多线程环境下性能会远远优于Log4j 1.x和logback (官方数据是10倍以上)。

三、Log4j2的简单使用

1、在pom.xml文件中引入Log4j2的依赖

<properties>
     <log4j.version>2.11.1</log4j.version>
</properties>

<dependencies>

  <dependency>
      <groupId>org.apache.logging.log4j</groupId>
      <artifactId>log4j-api</artifactId>
      <version>${log4j.version}</version>
  </dependency>

  <dependency>
      <groupId>org.apache.logging.log4j</groupId>
      <artifactId>log4j-core</artifactId>
      <version>${log4j.version}</version>
  </dependency>

</dependencies>

2、编写Log4j2Test测试类,进行简单测试

package com.log4j2.test;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;


public class Log4j2Test {

    //通过根日志名称来获取日志实例
    private static final Logger logger = LogManager.getLogger(LogManager.ROOT_LOGGER_NAME);

    public static void main(String[] args) {

        logger.trace("trace level");
        logger.debug("debug level");
        logger.info("info level");
        logger.warn("warn level");
        logger.error("error level");
        logger.fatal("fatal level");
    }

}

3、其运行结果如下所示

2019-08-17 11:19:11,993 main WARN No Root logger was configured, creating default ERROR-level Root logger with Console appender
11:19:12.118 [main] ERROR  - error level
11:19:12.118 [main] FATAL  - fatal level

结果说明:

     1、在项目中,我们只引入了Log4j2的依赖包并没有引入或者编写其相应的配置文件,在控制台输出了第一句,其解释为:没有配置根记录程序,使用控制台附加程序创建默认的错误级根记录程序

     2、可以看到控制台只输出了error 和 fatal级别的错误信息,其他级别的错误信息并没有被输出,是因为没有配置文件,则默认使用error级别并在控制台输出,所以只有error 或者比 error更高的级别 fatal被输出到控制台

    3、缺省的配置等同于如下其默认的配置 (相关配置会在后面进行统一讲解)

<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="WARN">

    <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="error">
            <AppenderRef ref="Console"/>
        </Root>
    </Loggers>
</Configuration>

四、Log4j2的日志名称层次输出规则

1、在com.log4j2包路径下创建一个名为Log4j2类

package com.log4j2;


import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

public class Log4j2 {

    private static final Logger logger = LogManager.getLogger(Log4j2.class);

    public static void main(String[] args) {

        logger.info("INFO:Log4j2 --- info level");
        logger.warn("WARN:Log4j2 --- warn level");
        logger.error("ERROR:Log4j2 --- error level");
    }
}

2、在src/main/resources目录下,创建一个名为log4j2.xml的配置文件 (注意:配置文件的名称最好为log4j2.xml,因为log4j2默认会去找一个名为log4j2.xml的配置文件)

<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="WARN">

    <Appenders>
       <Console name="Console" target="SYSTEM_OUT">
           <PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/>
       </Console>
    </Appenders>
    <Loggers>
        <Logger name="com.log4j2.Log4j2" level="info">
            <AppenderRef ref="Console"/>
        </Logger>

        <Logger name="com.log4j2" level="warn">
            <AppenderRef ref="Console"/>
        </Logger>

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

3、其运行结果如下所示

14:13:47.526 [main] INFO  com.log4j2.Log4j2 - INFO:Log4j2 --- info level
14:13:47.526 [main] INFO  com.log4j2.Log4j2 - INFO:Log4j2 --- info level
14:13:47.526 [main] INFO  com.log4j2.Log4j2 - INFO:Log4j2 --- info level
14:13:47.529 [main] WARN  com.log4j2.Log4j2 - WARN:Log4j2 --- warn level
14:13:47.529 [main] WARN  com.log4j2.Log4j2 - WARN:Log4j2 --- warn level
14:13:47.529 [main] WARN  com.log4j2.Log4j2 - WARN:Log4j2 --- warn level
14:13:47.529 [main] ERROR com.log4j2.Log4j2 - ERROR:Log4j2 --- error level
14:13:47.529 [main] ERROR com.log4j2.Log4j2 - ERROR:Log4j2 --- error level
14:13:47.529 [main] ERROR com.log4j2.Log4j2 - ERROR:Log4j2 --- error level

结果说明:

     1、在控制台中,我们可以看到,同样的日志信息被输出了三次,细心的小伙伴们就会发现,名为"com.log4j2.Log4j2"的子级Logger的level=info,而名为"com.log4j2"的父级Logger的level=warn 和 顶级Root的level=error,都比子级Logger的level级别要高,那为什么低级别的信息,例如:info信息,还会被父级Logger 和 顶级Root输出打印呢?这是因为<Logger>标签中的additivity默认为true,即允许同时输出日志到父级的Appender中。同时Logger的命名符合命名层次规则,即一个Logger的名称是另一个Logger名称的前缀,则称其为另一个Logger的祖先或者父级,例如:名为com.log4j2的Logger 是名为com.log4j2.Log4j2的Logger的祖先或者父级

     2、同时Logger的命名和类的命名也有关联,当我们在配置文件中配置一个名为com.log4j2.Log4j2的Logger,那么在com.log4j2.Log4j2类中的Logger就会匹配到这一配置

    3、Root是整个命名层次规则的顶层,所以在输出日志时,配置文件中的二个Logger 和 Root对应的Appender会分别被调用

    4、如果你不想日志输出到父级的Appender中,则在<Logger>标签中配置additivity="false"即可

4、修改名为"com.log4j2.Log4j2"的Logger的level,由info 修改为 error,其他配置不变

<Logger name="com.log4j2.Log4j2" level="error">
   <AppenderRef ref="Console"/>
</Logger>

5、其运行结果如下所示

09:41:42.127 [main] ERROR com.log4j2.Log4j2 - ERROR:Log4j2 --- error le
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值