Java日志框架LOG4J2的介绍和使用

前置知识: 日志门面SLF4J介绍和使用

推荐阅读: Java日志框架Logback介绍和使用

log4j2概述

Apache Log4j2是对Log4j的升级版,参考了logback的一些优秀的设计,并且修复了一些问题,因此带来了一些重大的提升,主要有:

  • 异常处理,在logback中, Appender中的异常不会被应用感知到,但是在log4j2中,提供了一些异常处理机制。
  • 性能提升,log4j2相较于log4j和logback都具有很明显的性能提升。
  • 自动重载配置,参考了logback的设计,当然会提供自动刷新参数配置,最实用的就是我们在生产上可以动态地修改日志的级别而不需要重启应用。
  • 无垃圾机制,log4j2在大部分情况下,都可以使用其设计的一套无垃圾机制,避免频繁的日志收集导致的jvm gc。

Log4j2其实也是一个日志门面,但slf4j已经足够优秀,较少人把Log4j2用作日志门面,通常还是把它当成一个日志实现搭配slf4j使用。

log4j2日志门面

简要介绍一下log4j2作为日志门面的使用

maven依赖:

<dependency>
    <groupId>org.apache.logging.log4j</groupId>
    <artifactId>log4j-api</artifactId>
    <version>2.12.1</version>
</dependency>
<dependency>
    <groupId>org.apache.logging.log4j</groupId>
    <artifactId>log4j-core</artifactId>
    <version>2.12.1</version>
</dependency>

这样使用的就是Log4j2日志门面+本身的实现

public static final Logger LOGGER = LogManager.getLogger(LOG4J2Test.class);

@Test
public void testQuick() {
    LOGGER.fatal("fatal");
    LOGGER.error("error");
    LOGGER.warn("warn");
    LOGGER.info("info");
    LOGGER.debug("debug");
    LOGGER.trace("trace");
}

log4j2+slf4j使用

maven配置

<!-- slf4j日志门面 -->
<dependency>
    <groupId>org.slf4j</groupId>
    <artifactId>slf4j-api</artifactId>
    <version>1.7.30</version>
</dependency>
<!-- log4j2适配器 -->
<dependency>
    <groupId>org.apache.logging.log4j</groupId>
    <artifactId>log4j-slf4j-impl</artifactId>
    <version>2.13.0</version>
</dependency>
<!-- log4j2 -->
<dependency>
    <groupId>org.apache.logging.log4j</groupId>
    <artifactId>log4j-core</artifactId>
    <version>2.13.0</version>
</dependency>

这是最简单的写法,log4j-slf4j-impl依赖于log4j-api,它更像是桥接Log4j2日志门面。

使用就是SLF4J的使用方法(假设你没跳前置知识?)

log4j2配置

log4j2默认加载classpath下的log4j2.xml文件中的配置

它和logback实在是太像了,毕竟本来就是抄袭的logback(这是可以说的吗?)

logback的配置见Java日志框架Logback介绍和使用

所以我把配置贴出来应该就能看懂:

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

<!-- status,代表日志框架本身的输出日志级别;monitorInterval,配置为120,单位为秒。类似于logback的scanPeriod -->
<Configuration status="WARN" monitorInterval="120">

    <!-- 类似于logback的property,但是放入了properties节点 -->
    <properties>
        <property name="LOG_HOME">/logs</property>
    </properties>

    <!-- 将所有Appender放入了Appenders节点 -->
    <Appenders>
        <!--Console节点就直接指定了这个appender使用的类是logback自带的,name是自己命名的,target=SYSTEM_OUT表示输出到控制台。-->
        <Console name="Console" target="SYSTEM_OUT">
            <!--pattern和logback几乎也没有区别-->
            <PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] [%-5level] %c{36}:%L --- %m%n"/>
        </Console>

        <!--File节点就直接指定了这个appender使用的类是logback自带的,fileName指定文件路径,可以使用属性值${},append="true"追加到文件末尾-->
        <File name="log" fileName="${LOG_HOME}/test.log" append="true">
            <PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] [%-5level] %c{36}:%L --- %m%n"/>
        </File>

        <!--RandomAccessFile,文件随机读写流Appender,比File性能较好-->
        <RandomAccessFile name="log" fileName="${LOG_HOME}/test.log">
            <PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] [%-5level] %c{36}:%L --- %m%n"/>
        </RandomAccessFile>

        <!--RollingFile或使用RollingRandomAccessFile,自动拆分的文件随机读写流Appender, filePattern:历史日志封存路径。log4j2也自动识别zip等后缀,表示历史日志需要压缩。-->
        <RollingRandomAccessFile name="File" immediateFlush="true" fileName="${LOG_HOME}/today.log"
                                 filePattern="${LOG_HOME}/$${date:yyyy-MM-dd}/myrollog-%d{yyyy-MM-dd}-%i.log">
            <!-- 和logback的过滤器类似,onMatch、onMismatch可以为NEUTRAL表示中立 -->
            <Filters>
                <!-- 日志级别过滤器 -->
                <ThresholdFilter level="INFO" onMatch="ACCEPT" onMismatch="DENY"/>
            </Filters>

            <PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] [%-5level] %c{36}:%L --- %m%n" />
            <!--
                也可以是类似于logback的HTMLLayout
                <HTMLLayout pattern="%d{HH:mm:ss.SSS}%t%-5level%c{36}%L%m%n" />
            -->

            <!--RollingRandomAccessFile的必配项,TriggeringPolicy(触发策略) -->
            <Policies>
                <!--在系统启动时,触发拆分规则,产生一个新的日志文件-->
                <OnStartupTriggeringPolicy />
                <!--按时间划分日志文件,单位是filePattern中配置的 -->
                <TimeBasedTriggeringPolicy />
                <!--按大小划分日志文件-->
                <SizeBasedTriggeringPolicy size="10 MB" />
            </Policies>

            <!--覆盖策略,限定同一个目录下日志文件的最大数量-->
            <DefaultRolloverStrategy max="20"/>
        </RollingRandomAccessFile>
    </Appenders>

    <!-- 配置Root Logger和自定义logger -->
    <Loggers>
        <Root level="trace">
            <AppenderRef ref="Console"/>
        </Root>
    </Loggers>

</Configuration>

异步日志

Log4j2提供了AsyncAppender和AsyncLogger,通过BlockingQueue来实现异步。(比logback做的更全面一点)

通常使用AsyncLogger。

使用异步日志需要配置依赖:

<dependency>
    <groupId>com.lmax</groupId>
    <artifactId>disruptor</artifactId>
    <version>3.4.2</version>
</dependency>

使用AsyncAppender

这种方式和logback类似

<Appenders>
    <Async name="Async">
        <AppenderRef ref="file" />
    </Async>
</Appenders>

<Loggers>
    <Root level="trace">
        <AppenderRef ref="Console"/>
        <AppenderRef ref="Async"/>
    </Root>
</Loggers>

使用AsyncLogger

这种方法异步性能更高一点

全局异步

所有日志都异步,在配置文件上不用做任何改动,只需要添加一个log4j2.component.properties配置:

Log4jContextSelector=org.apache.logging.log4j.core.async.AsyncLoggerContextSelector

混合异步

可以在应用中同时使用同步日志和异步日志,这使得日志的配置方式更加灵活。

需要配置自定义logger:

<Loggers>
    <!-- includeLocation关闭文件信息、行号信息,这些信息影响性能 -->
    <AsyncLogger name="com.rhett.AsyncLogger" level="trace" includeLocation="false" additivity="false"> 
        <AppenderRef ref="file" />
    </AsyncLogger>
</Loggers>

原创文章,作者:彭晨涛,如若转载,请注明出处:https://www.codetool.top/article/java%e6%97%a5%e5%bf%97%e6%a1%86%e6%9e%b6log4j2%e7%9a%84%e4%bb%8b%e7%bb%8d%e5%92%8c%e4%bd%bf%e7%94%a8/

(0)
彭晨涛彭晨涛管理者
上一篇 2020年3月9日
下一篇 2020年3月10日

相关推荐

发表回复

登录后才能评论