最近项目里用到了Log4j2
,在这里咱们就不谈Log4j2
性能了,可以看一下官方给的测评图,真香。
但是使用时因为和Log4j
配置上有很大区别,也踩了不少坑,这里总结一下。
1.包依赖
使用Log4j2
首先要引入Log4j2
的包依赖,这里以maven
依赖为例。
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId>
<version>2.12.1</version>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-api</artifactId>
<version>2.12.1</version>
</dependency>
当然如果你想使用Slf4j
,可以直接添加以下依赖:
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-slf4j-impl</artifactId>
<version>2.12.1</version>
</dependency>
log4j-slf4j-impl
是一个完整的实现包,会自动引入log4j
和slf4j
需要的包依赖,见下图:
当然,Log4j2
如此好的性能,是因为它采用了异步模式进行日志的打印,要想实现Log4j2
的性能完全体,需要大名鼎鼎的disruptor
,因此我们引入:
<dependency>
<groupId>com.lmax</groupId>
<artifactId>disruptor</artifactId>
<version>3.4.2</version>
</dependency>
好的,引入了这么多依赖,这时候我们在项目目录下建一个log4j2.xml
的配置文件
2.打印到控制台
打印到控制台比较简单,这里还能给你打印彩色的日志到控制台:
<?xml version="1.0" encoding="UTF-8"?>
<configuration status="INFO">
<Properties>
<!-- 日志时间格式定义-->
<Property name="LOG_DATE_FORMAT_PATTERN">yyyy-MM-dd HH:mm:ss</Property>
<!-- 控制台日志颜色定义-->
<Property name="CONSOLE_COLOR_PATTERN">FATAL=Bright Red, ERROR=Bright Red, WARN=Bright Yellow, INFO=Bright blue,
DEBUG=Bright White, TRACE=Bright White
</Property>
<!-- 日志格式定义-->
<Property name="COMMON_LOG_PATTERN">%d{${LOG_DATE_FORMAT_PATTERN}} %-5p %C:%L - %m%n</Property>
</Properties>
<appenders>
<!--这个输出控制台的配置-->
<console name="Console" target="SYSTEM_OUT">
<!--输出日志的格式-->
<PatternLayout
pattern="%highlight{${COMMON_LOG_PATTERN}}{${CONSOLE_COLOR_PATTERN}}"/>
</console>
</appenders>
<loggers>
<asyncRoot level="info" includeLocation="true">
<appender-ref ref="Console"/>
</asyncRoot>
</configuration>
3.文件日志配置
现在我们假设需要打印3份日志:
- 除去MQ和RPC以外的全部日志
- MQ日志
- RPC日志
先看一下我们的配置文件:
<?xml version="1.0" encoding="UTF-8"?>
<configuration status="INFO">
<Properties>
<!-- property相当于配置变量 -->
<Property name="LOG_DIR">/export/Logs/my/</Property>
<!-- 日志时间格式定义-->
<Property name="LOG_DATE_FORMAT_PATTERN">yyyy-MM-dd HH:mm:ss</Property>
<!-- 日志格式定义-->
<Property name="COMMON_LOG_PATTERN">%d{${LOG_DATE_FORMAT_PATTERN}} %-5p %C:%L - %m%n</Property>
</Properties>
<appenders>
<!-- 项目日常日志 -->
<RollingRandomAccessFile
name="rollingFileDaily"
fileName="${LOG_DIR}/cringkong.log"
filePattern="${LOG_DIR}/cringkong.log.%d{yyyy-MM-dd}"
ignoreExceptions="false"
append="true">
<!-- 这里使用我们定义好的日志格式 -->
<PatternLayout pattern="${COMMON_LOG_PATTERN}"/>
<!-- 这里是基于时间触发的滚动日志策略,根据上面filePattern的定义,日志文件会一天分割出来一个 -->
<Policies>
<TimeBasedTriggeringPolicy/>
</Policies>
</RollingRandomAccessFile>
</appenders>
<loggers>
<!-- 这里以async作为前缀的ROOT和Logger默认是纯异步模式 -->
<asyncRoot level="info" includeLocation="true">
<appender-ref ref="rollingFileDaily"/>
</asyncRoot>
</loggers>
</configuration>
</configuration>
3.1 Properties标签
现在来详细说下配置的含义:
<Properties>
<!-- property相当于配置变量 -->
<Property name="LOG_DIR">/export/Logs/my/</Property>
</Properties>
Properties
标签里面的数据,相当于一个配置变量,name
相当于变量名,Property
标签里的数据相当于变量内容,我们在后面可以直接用${LOG_DIR}
来获取标签内变量的内容。
3.2 appenders标签
appenders
标签内主要用来配置Appender
打印日志的格式和策略,允许配置多个Appender
打印到不同的输出文件,Appenders标签,常见的有三种配置子标签有: Console、RollingFile、File。 Console上面我们已经用过了,可以打印到控制台,File和RollingFile都可以打印日志到文件,RollingFile支持滚动日志文件。
<appenders>
<!-- 使用RollingFile滚动切割日志文件 -->
<RollingRandomAccessFile
name="rollingFileDaily"
fileName="${LOG_DIR}/cringkong.log"
filePattern="${LOG_DIR}/cringkong.log.%d{yyyy-MM-dd}"
ignoreExceptions="false"
append="true">
<!-- 这里使用我们定义好的日志格式 -->
<PatternLayout pattern="${COMMON_LOG_PATTERN}"/>
<!-- 这里是基于时间触发的滚动日志策略,根据上面filePattern的定义,日志文件会一天分割出来一个 -->
<Policies>
<TimeBasedTriggeringPolicy/>
</Policies>
</RollingRandomAccessFile>
</appenders>
appenders
用来配置日志打印格式,RollingRandomAccessFile
支持日志文件的滚动分割,我们知道log4j
里可以直接配置每天切割日志文件,Log4j2
里配置提供的更加灵活。
name
就是appender
的名,不做过多说明,fileName
是直接打印日志文件的名,filePattern
是滚动文件的格式,我们来详细说说它。
3.3 日志文件滚动机制
RollingFile
实现日志文件滚动更新,依赖于TriggeringPolicy
和RolloverStrategy
配置,TriggeringPolicy
为滚动触发策略,其决定了何时触发日志文件的滚动切割,RolloverStrategy
为滚动更新策略,其决定了当触发了日志文件的滚动时,如何进行文件的切割。
RollingFile
的触发日志文件滚动的策略有:
- CronTriggeringPolicy(Cron表达式控制触发)
- OnStartupTriggeringPolicy(JVM启动时触发)
- SizeBasedTriggeringPolicy(基于文件大小触发,常用)
- TimeBasedTriggeringPolicy(基于时间触发,常用)
- CompositeTriggeringPolicy(多个触发策略的混合,如同时基于文件大小和时间)
这里我们模拟日常生产环境需要,采用基于时间触发的策略,每天触发一次日志文件滚动:
filePattern="${LOG_DIR}/cringkong.log.%d{yyyy-MM-dd}"
<!-- 这里是基于时间触发的滚动日志策略,根据上面filePattern的定义,日志文件会一天分割出来一个 -->
<Policies>
<TimeBasedTriggeringPolicy/>
</Policies>
TimeBasedTriggeringPolicy
规定了当日志文件名中的date/time pattern
不再符合filePattern
中的date/time pattern
时,触发日志文件滚动操作。
比如,filePattern指定文件重命名规则为.../cringkong.log.%d{yyyy-MM-dd}
,当前日志文件名为.../cringkong.log
,当时间达到2019年12月12日,触发一次日志文件滚动操作,日志滚动会生成新文件.../cringkong.log.2019-12-10
。
日志目录下会如:
/export/Logs/my/cringkong.log
/export/Logs/my/cringkong.log.2019-12-10
/export/Logs/my/cringkong.log.2019-12-11
目前我们线上项目的日志目录:
当然也可以根据小时或分钟滚动。
%d{yyyy-MM-dd-HH}
%d{yyyy-MM-dd-HH-mm}