一、配置文件

常用配置选项

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

<configuration status="WARN" monitorInterval="30" >
	<!--配置常量-->
	<properties></properties>
	<!--扩展、插件(可选项)-->
	<Appenders></Appenders>
	<Loggers></Loggers>
</configuration>

(一)动态刷新配置——monitorInterval

monitorInterval:从文件配置时,Log4j 能够自动检测对配置文件的更改并重新配置自身。如果在配置元素上指定了 monitorInterval 属性并将其设置为非零值,则在下次评估和/或记录日志事件时将检查该文件,并且自上次检查以来已经过去了 monitorInterval。下面的示例显示了如何配置该属性,以便仅在经过至少 30 秒后才检查配置文件的更改。最小间隔为 5 秒

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

<configuration status="error" monitorInterval="30">
</configuration>

(二)Configuration的status属性

Configuration后面的status,这个用于设置log4j2自身内部的信息输出,可以不设置,当设置成trace时,你会看到log4j2内部各种详细输出。
status 属性的有效值为“trace”、“debug”、“info”、“warn”、“error”和“fatal”。以下配置将状态属性设置为调试。

<configuration status="error" monitorInterval="30">
</configuration>

(三)日志级别——通过属性level指定

日志级别从低到高分为TRACE < DEBUG < INFO < WARN < ERROR < FATAL,如果设置为WARN,则低于WARN的信息都不会输出。对于Loggers中level的定义同样适用。
例子:

<Logger name="myLog" level="trace" additivity="false">
   <appender-ref ref="console"/>
</Logger>
	public static void main(String[] args) {
		Logger logger = LogManager.getLogger("mylog");
		logger.trace("trace level");
		logger.debug("debug level");
		logger.info("info level");
		logger.warn("warn level");
		logger.error("error level");
		logger.fatal("fatal level");
	}

(四)Logger与Root标签

可以简单的将Root认为默认的日志输出控制,并且这个默认的输出是不会被覆盖的。也就是当你输出日志的时候只要日志级别比Root指定的低那么一定会输出。

<Loggers>
    <Logger name="myLog" level="trace" additivity="false">
        <appender-ref ref="console"/>
    </Logger>
    <Root level="info">
        <AppenderRef ref="Console" />
    </Root>
</Loggers>

例子:

  1. 只配置Root
<Loggers>
    <Root level="info">
        <AppenderRef ref="Console" />
    </Root>
</Loggers>
public class Log4j2Test {
    private static final Logger logger = LogManager.getLogger();
    @Test
    public void test(){
        logger.trace("trace level");
        logger.debug("debug level");
        logger.info("info level");
        logger.warn("warn level");
        logger.error("error level");
        logger.fatal("fatal level");
    }
}

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

  1. 增加一个Logger 配置名字为myLog
    注意:name的值随意,一般为类路径。name的值可以重复,但是重复的name只有一个会生效
<Loggers>
    <Logger name="myLog" level="trace">
        <appender-ref ref="console"/>
    </Logger>
    <Root level="info">
        <AppenderRef ref="Console" />
    </Root>
</Loggers>
public class Log4j2Test {
    private static final Logger logger = LogManager.getLogger("myLog");
    @Test
    public void test(){
        logger.trace("trace level");
        logger.debug("debug level");
        logger.info("info level");
        logger.warn("warn level");
        logger.error("error level");
        logger.fatal("fatal level");
    }
}

输出:你会发现每条日志都重复输出了。这是因为Root和Logger叠加在一起了,并且还是以日志级别高的为准。那么我们可以避免叠加吗?当然可以,Logger 的additivity属性就可以做到。
在这里插入图片描述

(五)Log4j2.xml 对大小写不敏感

注意:Log4j2对大小写不敏感,AppenderRef == appender-ref。configuration ==Configuration

(六)Logger 的additivity属性

Logger 的additivity属性默认为true也就是可以叠加的。如果我们不想要日志叠加输出,那么可以将值设置为false。

<Loggers>
    <Logger name="myLog" level="trace" additivity="false">
        <appender-ref ref="console"/>
        <appender-ref ref="brokerLog-appender"/>
    </Logger>
    <Root level="info">
        <AppenderRef ref="Console" />
    </Root>
</Loggers>

(七)appender-ref的ref属性

<Loggers>
    <Logger name="myLog" level="trace" additivity="false">
    	<!-- 将日志输出到console -->
        <appender-ref ref="console"/>
        <!-- 将日志输出到brokerLog-appender-->
        <appender-ref ref="brokerLog-appender"/>
    </Logger>
    <Root level="info">
        <AppenderRef ref="Console" />
    </Root>
</Loggers>

注意:ref的值为appenders标签里面定义的appender(扩展、插件)的name的值。
在这里插入图片描述

二、appender

(一)Console

参数名 类型 描述
filter Filter 指定一个过滤器来决定是否将日志事件传递给 Appender 处理。可以指定为一个 CompositeFilter 来使用多个过滤器。
layout Layout 指定格式化 LogEvent 的 Layout。如果没有指定 Layout,则默认使用 %m%n 格式。
follow boolean 在配置好之后,是否可以通过 System.setOut 或 System.setErr 来重新指定输出位置为 System.out 或 System.err。不能在 Windows 下用于 Jansi ,也不能和 direct 属性一起使用。
direct boolean 绕开 java.lang.System.out/.err 直接写入 java.io.FileDescriptor。当输出重定向到文件或其他目标时可以节约 10 倍的性能消耗。不能在 Windows 下用于 Jansi,也性不能和 follow 属性一起使用。在多线程应用中,输出不会遵循 java.lang.System.setOut()/.setErr() ,而是可能会和其他输出纠缠在一起输出到 java.lang.System.out/.err。该属性是 2.6.2 版本新增的,目前仅在 Linux 和 Windows 下的 Oracle JVM 环境中测试过。
name String 必选的 Appender 的名称,表示区别于其他 Appender 的唯一标识。
ignoreExceptions boolean 默认为 true,表示当输出事件时出现的异常将会被内部记录而忽略。 当设置为 false 时,则会将异常传播给调用者。当将该 Appender 包装成 FailoverAppender 时,必须设置为 false
target String SYSTEM_OUTSYSTEM_ERR。默认为 SYSTEM_OUT
<Appenders>
	<Console name="STDOUT" target="SYSTEM_OUT">
	  <PatternLayout pattern="%m%n"/>
	</Console>
</Appenders>

(二)RollingRandomAccessFile

RollingRandomAccessFile 有一下属性

参数名 类型 描述
append boolean 当为 true(默认)时,日志记录将会添加到文件末尾。设置为 false 时,日志记录写入文件之前会清空文件。
bufferedIO boolean 当为 true(默认)时,日志记录将会写入一个缓冲区,当缓冲区满或设置了 immediateFlush ,日志记录才会写入磁盘中。 该属性不能使用文件锁。缓冲 I/O 能够显著提高性能,即使启用了immediateFlush 。
bufferSize int 当 bufferedIO 为 true 时,该属性用来设置缓冲区的大小,默认为 8192 字节。
createOnDemand boolean Appender 是按需(on-demand)创建文件的。仅当日志事件通过所有过滤器并到达 Appender 时,该 Appender 才会创建文件。默认为 false。
filter Filter 指定一个过滤器来决定是否将日志事件传递给 Appender 处理。可以指定为一个 CompositeFilter 来使用多个过滤器。
fileName String 设置写入日志记录的文件名。如果该文件或其父目录不存在,则会自动创建。
filePattern String 归档日志文件的文件名模式(pattern)。该模式依赖于所用的 RolloverPolicy 。DefaultRolloverPolicy 可以接受兼容 SimpleDateFormat 的日期/时间或表示一个整数的计数器的 %i 。该模式也支持运行时插入值(interpolation),故任何 Lookup(比如 DateLookup)都可以包含该模式。
immediateFlush boolean 当为 true(默认)时,每次写入都会跟随一次 flush 。这将保证数据写入磁盘,但会影响性能。仅当使用异步 Logger 的 Appender 时设置每次写入都进行 flush 才有用。异步的 Logger 和 Appender 会在一批次的日志事件末尾自动 flush ,即使该属性设置为 false ,这种方式也可以保证数据写入磁盘,但是更有效率。
layout Layout 指定格式化 LogEvent 的 Layout 。如果没有指定 Layout ,则默认使用 %m%n 格式。
name String 必选的 Appender 的名称,表示区别于其他 Appender 的唯一标识。
policy TriggeringPolicy 设置确定是否创建文件的规则(policy)。
strategy RolloverStrategy 设置确定归档文件的文件名和位置的策略(strategy)。
ignoreExceptions boolean 默认为 true ,表示当输出事件时出现的异常将会被内部记录而忽略。 当设置为 false 时,则会将异常传播给调用者。当将该 Appender 包装成 FailoverAppender 时,必须设置为 false
filePermissions String 设置每当创建文件时所用的 POSIX 格式的文件属性权限。底层文件系统应该支持 POSIX 格式的文件属性视图。比如: rw——- 或 rw-rw-rw- 等。
fileOwner String 指定每次创建文件的属主。由于权限原因,可能不允许更改文件属主,这时会抛出 IOException 。仅当有效的目标用户 ID 和文件的用户 ID 相同,或目标用户 ID 具有修改文件属主的权限(如果 _POSIX_CHOWN_RESTRICTED 在日志文件路径下有效)时才会处理。底层文件系统应该支持 owner 文件属性视图。
fileGroup String 指定每次创建文件的属组。底层文件系统应该支持 POSIX 格式的文件属性视图。
<appenders>
    <!-- 这个会打印出所有的信息,每次大小超过size,则这size大小的日志会自动存入按年份-月份建立的文件夹下面并进行压缩,作为存档-->
    <RollingRandomAccessFile name="error-appender" fileName="${user.dir}/jmqttlogs/error.log" 
    			<!--将fileName日志文件的内容按照时间间隔复制到filePattern日志文件中。注意:通过 %d{yyyy-MM-dd}里面的日期格式可以控制多久生成一个日期文件-->
                 filePattern="${user.dir}/jmqttlogs/error.log.%d{yyyy-MM-dd}"
                 <!-- fileName是否追加写-->
                 append="true">
        <ThresholdFilter level="ERROR" onMatch="ACCEPT" onMismatch="DENY"/>
        <PatternLayout
                pattern="${pattern}"
                charset="UTF-8"/>
        <Policies>
        <!-- 指定时间的颗粒度,比如:interval="1",就是每1(分、小时、天)产生一个filePattern日志文件 -->    
            <TimeBasedTriggeringPolicy interval="1" />
            <SizeBasedTriggeringPolicy size="10 MB" />
        </Policies>
         <!-- DefaultRolloverStrategy属性如不设置,则默认为最多同一文件夹下7个文件,这里设置了10 -->
        <DefaultRolloverStrategy max="20">
        	<!-- 每10天删除一个日志文件-->
            <Delete basePath="${user.dir}" maxDepth="1">
                <IfFileName glob="*/common-error.log.*"/>
                <IfLastModified age="10d"/>
            </Delete>
        </DefaultRolloverStrategy>
    </RollingRandomAccessFile>
</appenders>

注意:

  1. TimeBasedTriggeringPolicy 这个配置需要和filePattern结合使用,注意filePattern中配置的文件重命名规则是${FILE_NAME}-%d{yyyy-MM-dd HH-mm}-%i,最小的时间粒度是mm,即分钟,TimeBasedTriggeringPolicy指定的size是1,结合起来就是每1分钟生成一个新文件。如果改成%d{yyyy-MM-dd HH},最小粒度为小时,则每一个小时生成一个文件。
  2. filePattern定义的是每天生成一个日志文件,但是如果一天内的日志文件体积已经超过50M,就从新生成,两个条件满足一个即可。
  3. filePattern 日志文件与 fileName 日志文件
    • fileName 指定当前日志文件的位置和文件名称
    • filePattern 指定当发生Rolling时,文件的转移和重命名规则
      在这里插入图片描述

(三)RollingFile

RollingFile 与RollingRandomAccessFile功能类似。

<RollingFile name="error-appender" fileName="${user.dir}/jmqttlogs/error.log"
            filePattern="${user.dir}/jmqttlogs/error.log.%d{yyyy-MM-dd}"
             append="true">
    <ThresholdFilter level="ERROR" onMatch="ACCEPT" onMismatch="DENY"/>
    <PatternLayout
            pattern="${pattern}"
            charset="UTF-8"/>
    <TimeBasedTriggeringPolicy/>
    <DefaultRolloverStrategy>
        <Delete basePath="${user.dir}" maxDepth="1">
            <IfFileName glob="*/common-error.log.*"/>
            <IfLastModified age="10d"/>
        </Delete>
    </DefaultRolloverStrategy>
</RollingFile>

三、Patterns

######### 常见参数 #########
//
%c{参数}%logger{参数}  ##输出日志名称
%C{参数}%class{参数    ##输出类型
%d{参数}{时区te{参数}{时区} ##输出时间
%F|%file                  ##输出文件名
highlight{pattern}{style} ##高亮显示
%l  ##输出错误的完整位置
%L  ##输出错误行号
%m 或 %msg 或 %message ##输出错误信息
%M%method ##输出方法名
%n            ##输出换行符
%level{参数1}{参数2}{参数3} ##输出日志的级别
%t 或 %thread              ##创建logging事件的线程名
*/

######### 特殊符号 ############
#有些特殊符号不能直接打印,需要使用实体名称或者编号
//
& —— &amp; 或者 &#38;
< —— &lt;  或者 &#60;
> —— &gt;  或者 &#62;
“ —— &quot; 或者 &#34;
‘ —— &apos; 或者 &#39;
*/

######## pattern对齐修饰 ##########

// 对齐修饰,可以指定信息的输出格式,如是否左对齐,是否留空格等。
## 编写格式为在任何pattern和%之间加入一个小数,可以是正数,也可以是负数。
## 整数表示右对齐,负数表示左对齐;
## 整数位表示输出信息的最小n个字符,如果输出信息不够n个字符,将用空格补齐;
## 小数位表示输出信息的最大字符数,如果超过n个字符,则只保留最后n个字符的信息
## (注意:保留的是后20个字符,而不是前20个字符)
*/

#示例如下
//

%20 —— 右对齐,不足20个字符则在信息前面用空格补足,超过20个字符则保留原信息
%-20 —— 左对齐,不足20个字符则在信息后面用空格补足,超过20个字符则保留原信息
%.30 —— 如果信息超过30个字符,则只保留最后30个字符
%20.30 —— 右对齐,不足20个字符则在信息前面用空格补足,超过30个字符则只保留最后30个字符
%-20.30 —— 左对齐,不足20个字符则在信息后面用空格补足,超过30个字符则只保留最后30个字符

参考:PatternLayout输出格式详解

四、Java 使用Log4j2

(一)导入pom依赖

<dependencies>
        <!--日志门面slf4j-->
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-api</artifactId>
            <version>${slf4j.version}</version>
        </dependency>
        <!---->
        <dependency>
            <groupId>org.apache.logging.log4j</groupId>
            <artifactId>log4j-slf4j-impl</artifactId>
            <version>${log4j2.version}</version>
        </dependency>
        <!--日志实现 log4j2-->
        <dependency>
            <groupId>org.apache.logging.log4j</groupId>
            <artifactId>log4j-core</artifactId>
            <version>${log4j2.version}</version>
        </dependency>
        <!--日志门面 log4j-->
        <dependency>
            <groupId>org.apache.logging.log4j</groupId>
            <artifactId>log4j-api</artifactId>
            <version>${log4j2.version}</version>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.18.20</version>
        </dependency>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.13.2</version>
            <!--<scope>test</scope>-->
        </dependency>
    </dependencies>

(二)配置Log4j2.xml

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

<configuration status="WARN" monitorInterval="5">

    <properties>
        <!-- 配置常量,用于宏设置属性 -->
        <property name="user.dir" value="./" />
        <property name="level" value="INFO"/>
        <property name="pattern" value="%d [%X{traceId}/%X{loginUserID}/%X{remoteAddr}/%X{clientId} - %X{requestURIWithQueryString}] %-5p %c{2} - %m%n"/>
    </properties>
    <Appenders>
        <Console name="Console" target="SYSTEM_OUT">
            <PatternLayout pattern="${pattern}" />
        </Console>

        <!--这个会打印出所有的信息,每次大小超过size,则这size大小的日志会自动存入按年份-月份建立的文件夹下面并进行压缩,作为存档
        将fileName日志文件的内容按照时间间隔复制到filePattern日志文件中。注意:通过 %d{yyyy-MM-dd}里面的日期格式可以控制多久生成一个日期文件
        append="true" fileName是否追加写
        -->
        <RollingRandomAccessFile  name="rolling-appender"
                         fileName="${user.dir}/logs/rolling.log"
                         filePattern="${user.dir}/logs/rolling.log.%d{yyyy-MM-dd hh-mm}"
                         append="true">
            <ThresholdFilter level="ERROR" onMatch="ACCEPT" onMismatch="DENY"/>
            <PatternLayout
                    pattern="${pattern}"
                    charset="UTF-8"/>
            <!-- 指定时间的颗粒度,比如:interval="1",就是每1(分、小时、天)产生一个filePattern日志文件 -->
            <Policies>
                <TimeBasedTriggeringPolicy interval="10" />
                <SizeBasedTriggeringPolicy size="10 MB" />
            </Policies>
            <!-- DefaultRolloverStrategy属性如不设置,则默认为最多同一文件夹下7个文件,这里设置了20 -->
            <DefaultRolloverStrategy max="20">
                <!-- 每10天删除一个日志文件-->
                <Delete basePath="${user.dir}" maxDepth="1">
                    <IfFileName glob="*/rolling.log.*"/>
                    <IfLastModified age="2m"/>
                </Delete>
            </DefaultRolloverStrategy>
        </RollingRandomAccessFile >
    </Appenders>
    <Loggers>
        <Logger name="myLog" level="${level}" additivity="false">
            <!--同时将日志输出到控制台和日志文件-->
            <AppenderRef ref="Console" />
            <AppenderRef ref="rolling-appender"/>
        </Logger>
        <Root level="${level}">
            <AppenderRef ref="Console" />
        </Root>
    </Loggers>

</configuration>

(三)使用日志

package com.lihua;

import lombok.extern.slf4j.Slf4j;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.apache.logging.log4j.core.config.ConfigurationSource;
import org.junit.Test;

/**
 * @author hs
 * @date 2021/11/18 14:41
 */
public class Log4j2Test {
    private static final Logger logger = LogManager.getLogger("myLog");
    @Test
    public void test(){
        for (int i = 0; i <2 ; i++) {
            logger.trace("trace level");
            logger.debug("debug level");
            logger.info("info level");
            logger.warn("warn level");
            logger.error("error level");
            logger.fatal("fatal level");

        }
    }
}

当然你也可以结合lombok 插件的@Slf4j注解使用

package com.lihua;

import lombok.extern.slf4j.Slf4j;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.apache.logging.log4j.core.config.ConfigurationSource;
import org.junit.Test;

/**
 * @author hs
 * @date 2021/11/18 14:41
 */
@Slf4j
public class Log4j2Test {
    @Test
    public void test1(){
        log.trace("trace level");
        log.debug("debug level");
        log.info("info level");
        log.warn("warn level");
        log.error("error level");
    }
}

(四)加载指定路径下的配置文件

注意:log4j2.xml文件如果在resources的根目录下是会主动加载log4j2.xml配置文件的,当log4j2.xml所在目录发生变化后,可能会出错。

五、比较完整的log4j2.xml配置

<?xml version="1.0" encoding="UTF-8"?>
<!--日志级别以及优先级排序: OFF > FATAL > ERROR > WARN > INFO > DEBUG > TRACE > ALL -->
<!--Configuration后面的status,这个用于设置log4j2自身内部的信息输出,可以不设置,当设置成trace时,你会看到log4j2内部各种详细输出-->
<!--monitorInterval:Log4j能够自动检测修改配置 文件和重新配置本身,可设置一个非零的间隔秒数来检测配置变更 -->
<Configuration status="WARN" monitorInterval="60">
    <!-- 自定义一些变量 -->
    <Properties>
        <!-- 变量定义 -->
        <Property name="log_base_dir">/app_data/logs/my_app</Property>
        <!-- Appender在将日志数据写入目标位置之前,一般会将日志数据通过Layout进行格式化。PatternLayout可以使用与C语言printf函数类似
        的转换模式来指定输出格式。常见的配置如下:
        - %d{yyyy-MM-dd HH:mm:ss.SSS} : 日志生成时间,输出格式为“年-月-日 时:分:秒.毫秒”
        - %p : 日志输出格式
        - %c : logger的名称
        - %m : 日志内容,即 logger.info("message")
        - %n : 换行符
        - %T : 线程号
        - %L : 日志输出所在行数
        - %M : 日志输出所在方法名 -->
        <Property name="log_pattern">[%d{yyyy-MM-dd HH:mm:ss.SSS}][%-5p][%T][%c.%M:%L] %msg%xEx%n</Property>
        <!-- 单个日志文件最大大小,单位可以是KB, MB or GB -->
        <Property name="max_single_file_size">1MB</Property>
    </Properties>

    <!-- 使用Appenders元素可以将日志事件数据写到各种目标位置(目前可以为控制台、文件、多种数据库API、远程套接字服务器、Apache Flume、
    JMS、远程UNIX Syslog daemon),其内的每个Appender都必须要有一个name属性作为唯一标识,该标识的值在Logger中通过AppenderRef来引
    用,从而将该Appender配置到该Logger中 -->
    <Appenders>
        <!-- Console Appender常用于将日志输出到System.out,一般用在开发环境 -->
        <Console name="Console" target="SYSTEM_OUT">
            <!-- 只接受程序中DEBUG级别的日志进行处理-->
            <ThresholdFilter level="DEBUG" onMatch="ACCEPT" onMismatch="DENY"/>
            <!-- 在大多数情况下,Appender将格式化LogEvent的责任委托给Layout -->
            <PatternLayout pattern="${log_pattern}"/>
        </Console>

        <!-- RollingFile Appender会将日志输出到fileName属性指定的文件中,且需要指定TriggeringPolicy和RolloverStrategy。其中
        TriggeringPolicy决定是否生成新的日志文件,RolloverStrategy决定如何生成新的日志文件。如果没有配置RolloverStrategy,则会
        使用DefaultRolloverStrategy。从2.5开始,可以在DefaultRolloverStrategy中配置一个自定义的删除动作。从2.8开始,如果没有指定
        文件名,则会使用DirectWriteRolloverStrategy来代替DefaultRolloverStrategy -->
        <!-- 这个RollingFile Appender会打印出所有的DEBUG及以下级别(DEBUG、INFO、ERROR、FATAL、OFF)的信息 -->
        <RollingFile name="DebugLogRollingFile" fileName="${log_base_dir}/my_app_debug.log"
                     filePattern="${log_base_dir}/$${date:yyyy_MM_dd}/my_app_debug_%d{yyyy_MM_dd_HH}_%i.log.gz">
            <ThresholdFilter level="DEBUG" onMatch="ACCEPT" onMismatch="DENY"/>
            <PatternLayout pattern="${log_pattern}" charset="UTF-8"/>
            <!-- Policies表示一个CompositeTriggeringPolicy,可以组合多个TriggeringPolicy,只要内部的任意一个TriggeringPolicy
            满足触发条件,都会滚动日志 -->
            <Policies>
                <!-- TimeBasedTriggeringPolicy用于按时间滚动日志。只要filePattern属性值中的日期/时间模式(pattern)不再应用于当
                前文件时就进行日志滚动。这种规则通过interval和modulate属性来配置。interval属性指定一个整数,用于基于日期/时间模式中
                的最小的时间单位数滚动一次。例如,filePattern值为/app_data/logs/my_app/$${date:yyyy_MM_dd}/my_app_%d{yyyy_
                MM_dd_HH}_%i.log,这里使用小时作为最小的时间单位时,假如interval参数值为4,则表示每4小时滚动一次。默认值为1。
                modulate表示是否调整interval属性值以便下次滚动发生在interval边界处。如果时间最小单位为小时,当前时间为早上3点,间隔
                为4小时,则第一次滚动将发生在早上4点时(而不是早上7点),后续滚动将发生在早上8点、中午12点、下午4点等时刻 -->
                <TimeBasedTriggeringPolicy interval="1" modulate="false"/>
                <!-- SizeBasedTriggeringPolicy用于按文件大小滚动日志。每当日志文件超过size指定的大小(一般不超过几十MB,否则使用软
                件打开导出的日志时很不方便),则这size大小的日志会自动存入按filePattern属性指定建立的文件夹下面并进行压缩存档 -->
                <SizeBasedTriggeringPolicy size="${max_single_file_size}"/>
            </Policies>
            <!-- DefaultRolloverStrategy可以同时接受RollingFileAppender中filePattern属性值中日期/时间和整数计数器(%i)的
            pattern,当日期/时间满足条件时,则会使用当前的日期/时间生成新的日志文件,如果filePattern属性值中含有一个整数计数器%i,则
            在每次滚动时该整数都会增加,如果filePattern属性值中同时包含了日期/时间和整数计数器(%i),计数器会在日期/时间不变时而满足
            其他滚动触发条件时(文件大小)开始自增,直到日期/时间发生变化时,计数器会重新自增。以.gz、.zip、.bz2、deflate、pack200
            或xz结尾的filePattern值,会在日志文件归档时以后缀对应的格式进行压缩。min属性指定计数器的最小值,默认为1。max属性指定计数
            器的最大值,一旦计数器达到了最大值,最早的归档将会在每次滚动时被删除,默认值为7。fileIndex属性如果设置为max(默认),则具
            有更大索引的文件比具有更小索引的文件内容更新,如果设置为min,文件将重命名且计数器将遵循Fixed Window策略,这两种情况均有可
            能导致批量的文件重命名,自2.8版本开始,如果fileIndex属性设置为nomax,则min和max属性值都将会被忽略,文件编号将每次递增1,
            每次滚动都会递增到更大的值,且没有最大文件编号的限制 -->
            <!--<DefaultRolloverStrategy max="100" min="1" fileIndex = "nomax"/>-->
            <DefaultRolloverStrategy fileIndex="nomax">
                <!-- Log4j 2.5引入了删除动作(Delete元素)。在滚动删除旧的日志文件时,相比使用DefaultRolloverStrategy的max属
                性,该功能可以让用户拥有更多的删除控制。删除动作可以让用户配置若干个条件来删除相对于基准目录的文件。该功能可以删除非日
                志文件,使用时一定要小心。可以通过testMode属性来测试配置是否会错删文件。basePath属性值用于指定删除文件的基准目录,必
                须显式指定。maxDepth属性指定扫描目录的最大层级,0表示仅能访问基准目录(安全限制不能访问的情况除外),
                Integer.MAX_VALUE值表示可以访问所有层级。默认值为1,表示仅扫描基准目录下的文件。testMode属性值如果设置为true,文件
                不会实际删除,而是在status logger打印一条INFO级别的消息,可以使用该功能来测试是否会错删目标文件,默认为false。-->

                <!-- 这里的Delete元素配置了每次滚动都会删除基准目录下匹配“*/my_app_debug_*.log.gz”日志文件,只要9分钟以前的日志文
                件总大小超过2MB,或9分钟以前的日志文件文件总数超过2个就按时间顺序删除较早的日志文件。该元素可以防止日志文件所在分区的
                磁盘空间被占满。特别需要注意的是,只有在发生日志滚动时才会尝试进行删除,否则即使满足了删除条件,但如果没有新的滚动日志
                生成的话也不会发生删除操作。 -->
                <Delete basePath="${log_base_dir}" maxDepth="2">
                    <!-- Delete元素里可以指定若干个PathCondition类型的元素。如果指定了不止一个条件,则这些条件都需要在删除之前接受
                    某个路径。这些条件可以嵌套,只有外部条件接受某个路径之后,其内部条件才会决定是否接受该路径。如果这些条件没有嵌套,
                    则它们的执行顺序是任意的。这些条件也可以通过使用IfAll, IfAny和IfNot等组合条件进行AND、OR和NOT等逻辑运算。用户
                    也可以创建自定义条件或使用内置条件:
                    - IfFileName:接受匹配正则表达式或glob的文件路径;
                    - IfLastModified:接受比指定时段早或一样早的文件;
                    - IfAccumulatedFileCount:在遍历文件树时文件总数超过文件数上限后接受路径;
                    - IfAccumulatedFileSize:在遍历文件树时文件总大小超过上限后接受路径;
                    - IfAll:如果所有内嵌条件都接受了某个路径才会接受该路径,相当于AND逻辑,其内嵌条件的执行顺序是任意的;
                    - IfAny:如果任意一个内嵌条件接受了某个目录就接受该目录,相当于OR逻辑,其内嵌条件的执行顺序是任意的;
                    - IfNot:如果内嵌条件不接受某个路径就接收该路径,相当于NOT逻辑。-->

                    <!-- IfFileName可以通过glob(使用受限的模式语言,比正则更简单)或regex属性(正则)来匹配相对路径(相对于Delete
                    的basePath属性指定的基准目录)-->
                    <!-- 当外部的条件满足时才会计算内部的条件,内部的同级条件的计算顺序是任意的。 -->
                    <IfFileName glob="*/my_app_debug_*.log.gz">
                        <!-- IfLastModified可以通过age属性值来指定接受最后修改时间为指定时间或早于指定时间的路径,该属性的值可参考
                        org.apache.logging.log4j.core.appender.rolling.action.Duration.parse(CharSequence text)方法的文档 -->
                        <!-- 这里的IfLastModified指定删除达到或超过60天内的文件 -->
                        <IfLastModified age="9m">
                            <!-- 这里的IfAny内嵌了两个PathCondition,表示满足任意一个条件即可 -->
                            <IfAny>
                                <!-- IfAccumulatedFileSize可通过exceeds属性值指定一个文件总大小上限值。如果文件数超过了该上限值
                                则删除文件 -->
                                <IfAccumulatedFileSize exceeds="2MB"/>
                                <!-- IfAccumulatedFileCount可通过exceeds属性值指定一个文件总数上限值。如果文件数超过了该上限值
                                则删除文件 -->
                                <IfAccumulatedFileCount exceeds="2"/>
                            </IfAny>
                        </IfLastModified>
                    </IfFileName>
                </Delete>
            </DefaultRolloverStrategy>
        </RollingFile>

        <RollingFile name="InfoLogRollingFile" fileName="${log_base_dir}/my_app_info.log"
                     filePattern="${log_base_dir}/$${date:yyyy_MM_dd}/my_app_info_%d{yyyy_MM_dd_HH}_%i.log.gz">
            <ThresholdFilter level="INFO" onMatch="ACCEPT" onMismatch="DENY"/>
            <PatternLayout pattern="${log_pattern}"/>
            <Policies>
                <TimeBasedTriggeringPolicy/>
                <SizeBasedTriggeringPolicy size="${max_single_file_size}"/>
            </Policies>
            <DefaultRolloverStrategy fileIndex="nomax">
                <Delete basePath="${log_base_dir}" maxDepth="2">
                    <IfFileName glob="*/my_app_info_*.log.gz">
                        <!-- 这里表示匹配“*/my_app_info_*.log.gz”模式的日志文件的删除策略如下:
                        - 只要日志文件总数量超过5个就删除按时间顺序最早的日志文件
                        - 只要日志文件总大小超过10MB就会删除按时间顺序最早的日志文件
                        - 只要日志文件最近修改时间为9分钟前或更早就会删除按时间顺序最早的日志文件 -->
                        <IfAny>
                            <IfAccumulatedFileSize exceeds="8MB"/>
                            <IfAccumulatedFileCount exceeds="5"/>
                            <IfLastModified age="9m"/>
                        </IfAny>
                    </IfFileName>
                </Delete>
            </DefaultRolloverStrategy>
        </RollingFile>

        <RollingFile name="WarnLogRollingFile" fileName="${log_base_dir}/my_app_warn.log"
                     filePattern="${log_base_dir}/$${date:yyyy_MM_dd}/my_app_warn_%d{yyyy_MM_dd_HH}_%i.log.gz">
            <ThresholdFilter level="WARN" onMatch="ACCEPT" onMismatch="DENY"/>
            <PatternLayout pattern="${log_pattern}"/>
            <Policies>
                <TimeBasedTriggeringPolicy/>
                <SizeBasedTriggeringPolicy size="${max_single_file_size}"/>
            </Policies>
            <DefaultRolloverStrategy fileIndex="nomax">
                <Delete basePath="${log_base_dir}" maxDepth="2">
                    <IfFileName glob="*/my_app_warn_*.log.gz">
                        <IfAny>
                            <IfAccumulatedFileSize exceeds="3GB"/>
                            <IfAccumulatedFileCount exceeds="3000"/>
                            <IfLastModified age="30d"/>
                        </IfAny>
                    </IfFileName>
                </Delete>
            </DefaultRolloverStrategy>
        </RollingFile>

        <RollingFile name="ErrorLogRollingFile" fileName="${log_base_dir}/my_app_error.log"
                     filePattern="${log_base_dir}/$${date:yyyy_MM_dd}/my_app_error_%d{yyyy_MM_dd_HH}_%i.log.gz">
            <ThresholdFilter level="ERROR" onMatch="ACCEPT" onMismatch="DENY"/>
            <PatternLayout pattern="${log_pattern}"/>
            <Policies>
                <TimeBasedTriggeringPolicy/>
                <SizeBasedTriggeringPolicy size="${max_single_file_size}"/>
            </Policies>
            <DefaultRolloverStrategy fileIndex="nomax">
                <Delete basePath="${log_base_dir}" maxDepth="2">
                    <IfFileName glob="*/my_app_error_*.log.gz">
                            <IfAny>
                            <IfAccumulatedFileSize exceeds="3GB"/>
                            <IfAccumulatedFileCount exceeds="3000"/>
                            <IfLastModified age="30d"/>
                        </IfAny>
                    </IfFileName>
                </Delete>
            </DefaultRolloverStrategy>
        </RollingFile>

        <!-- 记录druid的SQL语句 -->
        <RollingFile name="DruidSqlRollingFile" fileName="${log_base_dir}/druid.log"
                     filePattern="${log_base_dir}/$${date:yyyy_MM_dd}/druid_%d{yyyy_MM_dd_HH}_%i.log.gz">
            <PatternLayout pattern="${log_pattern}"/>
            <Policies>
                <TimeBasedTriggeringPolicy/>
                <SizeBasedTriggeringPolicy size="${max_single_file_size}"/>
            </Policies>
            <DefaultRolloverStrategy fileIndex="nomax">
                <Delete basePath="${log_base_dir}" maxDepth="2" testMode="true">
                    <IfFileName glob="*/druid_*.log.gz">
                        <IfAny>
                            <IfAccumulatedFileSize exceeds="3GB"/>
                            <IfAccumulatedFileCount exceeds="3000"/>
                            <IfLastModified age="30d"/>
                        </IfAny>
                    </IfFileName>
                </Delete>
            </DefaultRolloverStrategy>
        </RollingFile>
    </Appenders>

    <!--定义logger,只有定义了logger并引入的appender,appender才会生效-->
    <Loggers>
        <!-- 当Logger在配置文件中声明时,就创建了一个LoggerConfig对象,两者一一对应,LoggerConfig包含一些Filter、这些
        Filters用于过滤传递给任意Appender的LogEvent,它还包含一些Appender的引用。Logger本身执行无指向的动作,它仅含有一
        个与LoggerConfig关联的名称(通过name属性指定),root Logger具有固定的默认名称,其他Logger需要指定各自的name属性
        值。LoggerConfig会被分配一个日志级别,通过level属性来指定。内建的日志级别按优先级从高到底排序有:OFF > FATAL >
        ERROR > WARN > INFO > DEBUG > TRACE > ALL,Log4j 2 也支持自定义的日志级别。
        -->
        <Root level="ALL">
            <AppenderRef ref="Console"/>
            <AppenderRef ref="InfoLogRollingFile"/>
            <AppenderRef ref="WarnLogRollingFile"/>
            <AppenderRef ref="DebugLogRollingFile"/>
            <AppenderRef ref="ErrorLogRollingFile"/>
        </Root>

        <!-- 每个LoggerConfig的日志级别如果没有显式配置,则会继承其父级LoggerConfig的日志级别,而root LoggerConfig如果没
        有配置日志级别,则会为其分配一个默认的ERROR级别 -->
        <!-- 某个Logger所允许的每条日志打印请求都会传递给其LoggerConfig中的所有Appender,也会传递给该LoggerConfig的parent
        LoggerConfig中的Appender,这种现象称为相加性(Additivity)。也就是说,Appender会从LoggerConfig的继承中继承相加性。这种特
        性可以用来汇整某几个logger的输出,可以在声明Logger的配置文件中设置additivity="false"来禁用这种叠加继承 -->
        <!--记录druid-sql的记录-->
        <Logger name="druid.sql.Statement" level="debug" additivity="false">
            <appender-ref ref="DruidSqlRollingFile"/>
        </Logger>

        <!--过滤掉spring和mybatis的一些无用的DEBUG信息-->
        <Logger name="org.springframework" level="INFO"/>
        <Logger name="org.mybatis" level="INFO"/>

        <!--log4j2 自带过滤日志-->
        <Logger name="org.apache.catalina.startup.DigesterFactory" level="error"/>
        <Logger name="org.apache.catalina.util.LifecycleBase" level="error"/>
        <Logger name="org.apache.coyote.http11.Http11NioProtocol" level="warn"/>
        <Logger name="org.apache.sshd.common.util.SecurityUtils" level="warn"/>
        <Logger name="org.apache.tomcat.util.net.NioSelectorPool" level="warn"/>
        <Logger name="org.crsh.plugin" level="warn"/>
        <Logger name="org.crsh.ssh" level="warn"/>
        <Logger name="org.eclipse.jetty.util.component.AbstractLifeCycle" level="error"/>
        <Logger name="org.hibernate.validator.internal.util.Version" level="warn"/>
        <Logger name="org.springframework.boot.actuate.autoconfigure.CrshAutoConfiguration" level="warn"/>
        <Logger name="org.springframework.boot.actuate.endpoint.jmx" level="warn"/>
        <Logger name="org.thymeleaf" level="warn"/>
    </Loggers>
</Configuration>

六、参考

log4j2总结(这篇文章写得很详细,有log4j2.xml的详细配置)
官方文档
Log4j2配置文件详解


版权声明:本文为a123123sdf原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
原文链接:https://blog.csdn.net/a123123sdf/article/details/121399195