一、实战背景
在上一节log4j2配置文件中,我们简要介绍了log4j2的配置,本节我们就结合具体的项目需要来实现日志打印。在一般的项目中,我们日志会以文件的形式进行保存,但是如果日志文件一直保存,如果不及时清理总会打爆我们服务器的磁盘。所以在项目中一般使用RollingFile通过设置单个日志大小以及保存的日志数量进行回滚,总能保存最近一段时间的日志来帮助我们定位问题,查看日志。
二、项目实战
我们创建一个ThreadPoolExecutor线程池,提交10个线程,然后在每个线程中打印日志,同时,我们要实现日志回滚,我们确定最多保存10个日志文件,每个日志文件为1KB。
下面时log4j2.xml的配置
<?xml version="1.0" encoding="UTF-8"?>
<Configuration name="log-demo-config" status="error" monitorInterval="10">
<Appenders>
<!-- 默认保留Console,用于控制台日志输出 -->
<Console name="Console" target="SYSTEM_OUT">
<PatternLayout pattern="[%d{yyyy-MM-dd;HH:mm:ss.SSS Z}] [%-5p] [%t] [%c] %m%n"></PatternLayout>
</Console>
<!--
指定rollingFile的日志名称、文件路径,回滚格式(%i表示每次回滚会给日志加一个数字标识后缀
用来区分日志新旧)以及日志访问权限
PatternLayout 表示日志打印的格式
SizeBasedTriggeringPolicy 表示日志每存满1KB就回滚一次
DefaultRolloverStrategy 表示日志存满10个后,就会将最老的日志删除重新进行回滚
-->
<RollingFile name="ApiService"
filename="J:\JavaWorkSpace\SpringLearning\src\main\resources\log\api-service.log"
filepattern="J:\JavaWorkSpace\SpringLearning\src\main\resources\log\api-service.%i.log"
filePermissions="rw-------">
<PatternLayout pattern="[%d{yyyy-MM-dd HH:mm:ss,SSS Z}] [%-5p] [%t] [%c %L] %m%n"></PatternLayout>
<Policies>
<SizeBasedTriggeringPolicy size="1KB"></SizeBasedTriggeringPolicy>
</Policies>
<DefaultRolloverStrategy max="10"></DefaultRolloverStrategy>
</RollingFile>
</Appenders>
<Loggers>
<Logger name="com.demo.log" level="INFO" additivity="false">
<AppenderRef ref="ApiService"></AppenderRef>
</Logger>
</Loggers>
</Configuration>
上面我们将com.demo.log包下的日志全部用ApiService
打印,然后我们编写线程池打印日志代码,这里创建一个线程池,提交10个线程。
package com.demo.log;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.concurrent.LinkedBlockingDeque;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
public class LogDemo {
private static final Logger LOGGER = LoggerFactory.getLogger(LogDemo.class);
private static ThreadPoolExecutor threadPoolExecutor;
public static void main(String[] args) {
threadPoolExecutor = new ThreadPoolExecutor(10, 20, 1, TimeUnit.MINUTES, new LinkedBlockingDeque<>());
for (int i = 0; i < 10; i++) {
int threadNum = i;
threadPoolExecutor.execute(() -> {
while (true) {
LOGGER.info("thread-" + threadNum);
}
});
}
}
}
最后我们看日志打印效果:
日志存储文件加成功多出11个日志,其中10个为.数字.log
结尾,表明我们的回滚日志格式%i
生效了
filepattern="J:\JavaWorkSpace\SpringLearning\src\main\resources\log\api-service.%i.log"
日志格式如下,这是一个比较通用的格式,既有时间又有线程数、代码执行行数,方便快速定位问题,一般项目可以照搬一下。
pattern="[%d{yyyy-MM-dd HH:mm:ss,SSS Z}] [%-5p] [%t] [%c %L] %m%n"
[2021-09-08 22:16:53,590 +0800] [INFO ] [pool-2-thread-4] [com.demo.log.LogDemo 22] thread-3
[2021-09-08 22:16:53,589 +0800] [INFO ] [pool-2-thread-10] [com.demo.log.LogDemo 22] thread-9
[2021-09-08 22:16:53,607 +0800] [INFO ] [pool-2-thread-4] [com.demo.log.LogDemo 22] thread-3
[2021-09-08 22:16:53,589 +0800] [INFO ] [pool-2-thread-3] [com.demo.log.LogDemo 22] thread-2