log4j2学习(一)—介绍和使用

1 介绍

1.1 什么是log4j2

        log4j2是一个日志工具,用来打印程序的日志,方便开发人员便于排查问题等。

        根据官方文档说明:

    Apache Log4j 2 is an upgrade to Log4j that provides significant improvements over its predecessor, Log4j 1.x, and provides many of the improvements available in Logback while fixing some inherent problems in Logback’s architecture.

可以看出log4j2是log4j的重大升级,同时相比logback改进了一些自身存在的缺陷。

1.2 相对于log4j,它有哪些优势

  • 性能提升

    在多线程下,比log4j和logback的效率高18倍(来自官网文档)。

  • 支持更多APIs

  • 避免锁死(lock-in)

  • 自动加载配置文件

  • 更好用的过滤器

  • Garbage-free

    在stand-alone应用中是无垃圾的,在web应用中只有少量garbage。

  • log4j已经不再更新

    自从2015年8月5日,log4j官网宣布不再提供官网更新。

2 配置

2.1 默认配置

2.1.1 添加依赖

  • 普通Java Project

手动添加jar

log4j-api-2.11.1.jar
log4j-core-2.11.1.jar
  • Maven Project

    pom.xml里添加

    <dependencies>
      <dependency>
        <groupId>org.apache.logging.log4j</groupId>
        <artifactId>log4j-api</artifactId>
        <version>2.11.1</version>
      </dependency>
      <dependency>
        <groupId>org.apache.logging.log4j</groupId>
        <artifactId>log4j-core</artifactId>
        <version>2.11.1</version>
      </dependency>
    </dependencies>
    
  • Spring Boot

    pom.xml里添加

    <dependency>
    	<groupId>org.springframework.boot</groupId>
    	<artifactId>spring-boot-starter-log4j2</artifactId>
    	<version>1.5.8.RELEASE</version>
    </dependency>
    

2.1.2 测试代码

package top.yxdz.study.log4j2;

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

public class Log4jDisplay {

    //log4j使用LoggerFactory.getLogger()
    //log4j2使用LogManager.getLogger()
    private static final Logger LOG = LogManager.getLogger(Log4jDisplay.class);

    public static void main(String[] args){
        //日志级别高低:trace>Debug>info>warn>error>fatal
        LOG.trace("trace");
        LOG.debug("Debug...");
        LOG.info("Info...");
        LOG.warn("Warn...");
        LOG.error("Error...");
        LOG.fatal("Fatal...");
    }
}

2.1.3 测试结果

16:03:19.152 [main] ERROR top.yxdz.study.log4j2.Log4jDisplay - Error...
16:03:19.162 [main] FATAL top.yxdz.study.log4j2.Log4jDisplay - Fatal...

2.2 修改默认设置的输出格式

2.2.1添加log4j2.xml

2.2.1.1 自动加载配置文件规则

        log4j2.xml会自动加载自身配置文件,规则如下(按照如下顺序找配置文件,如果找到则终止后续查找):

  1. 查找系统配置文件是否配置log4j.configurationFile参数来指定配置文件位置

  2. 查找classpath目录下是否有log4j2-test.properties文件

  3. 查找classpath目录下是否有log4j2-test.yaml或者log4j2-test.yml文件

  4. 查找classpath目录下是否有log4j2-test.json或者log4j2-test.jsn文件

  5. 查找classpath目录下是否有log4j2-test.xml文件

  6. 查找classpath目录下是否有log4j2.properties文件

  7. 查找classpath目录下是否有log4j2.yaml或者log4j2.yml文件

  8. 查找classpath目录下是否有log4j2.json或者log4j2.jsn文件

  9. 查找classpath目录下是否有log4j2.xml文件

  10. 如果没有该文件,则加载默认配置

2.2.1.2 添加默认配置的log4j2.xml

        在classpath目录下添加log4j.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>
        <Root level="error">
            <AppenderRef ref="Console"/>
        </Root>
    </Loggers>
</Configuration>

2.2.2 格式说明

  • %d{HH:mm:ss.SSS} ——毫秒级的时间
  • %t——当前线程名
  • %-5level——日志级别,-5表示左对齐并且固定输出5个字符,如果不足在右边补0
  • %logger——logger名称
  • %msg——自定义的日志内容
  • %n——换行
  • %F——所在的类文件名
  • %L——行号
  • %M——所在方法名
  • %l——语句所在的行数, 包括类名、方法名、文件名、行数

2.2.3 修改配置

<?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} [%t] %-5level %l - %msg%n"/>
        </Console>
    </Appenders>
    <Loggers>
        <Root level="error">
            <AppenderRef ref="Console"/>
        </Root>
    </Loggers>
</Configuration>

2.2.4 测试结果

2018-12-24 17:12:07 [main] ERROR top.yxdz.study.log4j2.Log4jDisplay.main(Log4jDisplay.java:18) - Error...
2018-12-24 17:12:07 [main] FATAL top.yxdz.study.log4j2.Log4jDisplay.main(Log4jDisplay.java:19) - Fatal...

2.3 自定义Logger

2.3.1 功能说明

          通过添加Logger的方式,添加自定义Logger。这种方式,可以让一个系统内,对部分需要详细日志的地方可以打印出详细的日志,其他地方则照旧输出。

2.3.2 修改测试代码

package top.yxdz.study.log4j2;

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

public class Log4jDisplay {

    //log4j使用LoggerFactory.getLogger()
    //log4j2使用LogManager.getLogger()
//    private static final Logger LOG = LogManager.getLogger(Log4jDisplay.class);
    //自定义logger,名称为myLog,要与配置文件中的名称相同
    private static final Logger LOG = LogManager.getLogger("myLog");

    public static void main(String[] args){
        //日志级别高低:trace>Debug>info>warn>error>fatal
        LOG.trace("trace");
        LOG.debug("Debug...");
        LOG.info("Info...");
        LOG.warn("Warn...");
        LOG.error("Error...");
        LOG.fatal("Fatal...");
    }
}

2.3.3 修改配置

<?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} [%t] %-5level %l - %msg%n"/>
        </Console>
    </Appenders>
    <Loggers>
        <Root level="error">
            <AppenderRef ref="Console"/>
        </Root>
        <Logger name="myLog" level="info" additivity="false">
            <AppenderRef ref="Console"/>
        </Logger>
    </Loggers>
</Configuration>

2.3.4 测试结果

2018-12-24 17:17:59 [main] INFO  top.yxdz.study.log4j2.Log4jDisplay.main(Log4jDisplay.java:17) - Info...
2018-12-24 17:17:59 [main] WARN  top.yxdz.study.log4j2.Log4jDisplay.main(Log4jDisplay.java:18) - Warn...
2018-12-24 17:17:59 [main] ERROR top.yxdz.study.log4j2.Log4jDisplay.main(Log4jDisplay.java:19) - Error...
2018-12-24 17:17:59 [main] FATAL top.yxdz.study.log4j2.Log4jDisplay.main(Log4jDisplay.java:20) - Fatal...

2.4 自定义Appender

2.4.1 功能说明

        Appender是日志输出到达目标的事件响应,可以是输出到控制台、异步输出、输出到文件、输出到数据库、输出到flume等等。

         下面我们在上面输出到控制台之外,再将info级别的日志输出到文件User/weixiurui/Download/log/test.log的例子。更加详细的配置,请参考官网的Appender

2.4.2 修改配置文件

<?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} [%t] %-5level %l - %msg%n"/>
        </Console>
        <File name="MyFile" fileName="/Users/weixiurui/Downloads/log/test.log">
            <PatternLayout pattern="%d{yyyy-MM-dd HH:mm:ss} [%t] %-5level %l - %msg%n"/>
        </File>
    </Appenders>
    <Loggers>
        <Root level="error">
            <AppenderRef ref="Console"/>
        </Root>
        <Logger name="myLog" level="info" additivity="false">
            <AppenderRef ref="Console"/>
            <AppenderRef ref="MyFile"/>
        </Logger>
    </Loggers>
</Configuration>

2.4.3 测试结果

log4j2写文件日志

2.5 分割和备份日志文件

2.5.1 功能说明

        通过该功能,可以让日志文件不会过大,同时也能够自动压缩和放在对应文件夹,方便日后可能需要查找。

2.5.2 修改配置文件

<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="WARN">
    <properties>
        <property name="LOG_HOME">/Users/weixiurui/Downloads/log</property>
        <property name="FILE_NAME">test</property>
    </properties>
    <Appenders>
        <!-- 控制台日志 -->
        <Console name="Console" target="SYSTEM_OUT">
            <PatternLayout pattern="%d{yyyy-MM-dd HH:mm:ss} [%t] %-5level %l - %msg%n"/>
        </Console>

        <!-- 写入文件 -->
        <!--<File name="MyFile" fileName="${LOG_HOME}/${FILE_NAME}.log">-->
            <!--<PatternLayout pattern="%d{yyyy-MM-dd HH:mm:ss} [%t] %-5level %l - %msg%n"/>-->
        <!--</File>-->
        
        <!-- 日志文件自动压缩、存放 -->
        <RollingFile name="RollingFile" fileName="${LOG_HOME}/${FILE_NAME}.log"
                     filePattern="${LOG_HOME}/$${date:yyyy-MM}/${FILE_NAME}-%d{MM-dd-yyyy}-%i.log.gz">
            <PatternLayout pattern="%d{yyyy.MM.dd 'at' HH:mm:ss.SSS z} %-5level %class{36} %L %M - %msg%xEx%n" />
            <!-- 日志文件大小 -->
            <Policies>
                <TimeBasedTriggeringPolicy interval="1" />
                <SizeBasedTriggeringPolicy size="10 MB" />
            </Policies>
            <!-- 最多保留文件数 -->
            <DefaultRolloverStrategy max="10"/>
        </RollingFile>
    </Appenders>
    <Loggers>
        <Root level="error">
            <AppenderRef ref="Console"/>
        </Root>
        <Logger name="myLog" level="info" additivity="false">
            <!--<AppenderRef ref="Console"/>-->
            <!--<AppenderRef ref="MyFile"/>-->
            <AppenderRef ref="RollingFile" />
        </Logger>
    </Loggers>
</Configuration>

2.5.3 修改测试代码

package top.yxdz.study.log4j2;

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

public class Log4jDisplay {

    //log4j使用LoggerFactory.getLogger()
    //log4j2使用LogManager.getLogger()
//    private static final Logger LOG = LogManager.getLogger(Log4jDisplay.class);
    //自定义logger,名称为myLog,要与配置文件中的名称相同
    private static final Logger LOG = LogManager.getLogger("myLog");

    public static void main(String[] args){
        for(int i=0; i<100000; i++){
            //日志级别高低:trace>Debug>info>warn>error>fatal
            LOG.trace("trace");
            LOG.debug("Debug...");
            LOG.info("Info...");
            LOG.warn("Warn...");
            LOG.error("Error...");
            LOG.fatal("Fatal...");
        }
    }
}

2.5.4 测试结果

log4j日志自动压缩

2.6 按日志级别分别输出文件

2.6.1 功能说明

        可以根据实际需求,将info级别的日志、error级别日志等其他级别的日志,分别写入不同的文件中。

2.6.2 修改配置文件

        添加Filters即可实现。

<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="WARN">
    <properties>
        <property name="LOG_HOME">/Users/weixiurui/Downloads/log</property>
        <property name="FILE_NAME">test</property>
    </properties>
    <Appenders>
        <!-- 控制台日志 -->
        <Console name="Console" target="SYSTEM_OUT">
            <PatternLayout pattern="%d{yyyy-MM-dd HH:mm:ss} [%t] %-5level %l - %msg%n"/>
        </Console>

        <!-- 写入文件 -->
        <!--<File name="MyFile" fileName="${LOG_HOME}/${FILE_NAME}.log">-->
            <!--<PatternLayout pattern="%d{yyyy-MM-dd HH:mm:ss} [%t] %-5level %l - %msg%n"/>-->
        <!--</File>-->

        <!-- 日志文件自动压缩、存放 -->
        <RollingFile name="errorFile" fileName="${LOG_HOME}/error.log"
                     filePattern="${LOG_HOME}/$${date:yyyy-MM}/${FILE_NAME}-%d{MM-dd-yyyy}-%i.log.gz">
            <PatternLayout pattern="%d{yyyy.MM.dd 'at' HH:mm:ss.SSS z} %-5level %class{36} %L %M - %msg%xEx%n" />
            <!-- 过滤器 -->
            <Filters>
                <ThresholdFilter level="error" onMatch="ACCEPT" onMismatch="DENY" />
            </Filters>
            <!-- 日志文件大小 -->
            <Policies>
                <TimeBasedTriggeringPolicy interval="1" />
                <SizeBasedTriggeringPolicy size="10 MB" />
            </Policies>
            <!-- 最多保留文件数 -->
            <DefaultRolloverStrategy max="10"/>
        </RollingFile>
    </Appenders>
    <Loggers>
        <Root level="error">
            <AppenderRef ref="Console"/>
        </Root>
        <Logger name="myLog" level="info" additivity="false">
            <!--<AppenderRef ref="Console"/>-->
            <!--<AppenderRef ref="MyFile"/>-->
            <AppenderRef ref="errorFile" />
        </Logger>
    </Loggers>
</Configuration>

2.6.3 测试结果

log4j2日志分类存储

3 遇到的问题

3.1 配置的log4j2.xml不生效

  • 起因

    配置好后,无论怎么更改log4j2.xml的配置文件,发现打印的日志级别根本没有改变

  • 解决

    经过排查,发现在启动的时候发现警告——jar冲突。log4j2使用的jar,和其他jar冲突(maven的配置),后来把冲突解决了,就正常了。

4 参考文章

Apache Log4j2官网

详解log4j2(上) - 从基础到实战

posted @ 2018-12-25 09:57  悠闲的宅  阅读(735)  评论(0编辑  收藏  举报