前言
生产环境bug,可以通过生成日志文件来查看原因
对比各种日志,决定选择logback,是log4j的升级版。
1、依赖pom.xml文件
<!-- logback 自动依赖了logback-core和slf4j-api -->
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
</dependency>
2、配置文件: logback-spring.xml (会自动读取,在resources目录下,也可以是logback.xml)
<?xml version="1.0" encoding="UTF-8"?>
<configuration scan="true" scanPeriod="10 seconds" debug="false">
<contextName>the-way-to-god</contextName>
<!-- 设置项目的id --> <!-- 设置日志文件名 -->
<property name="APP_ID" value="the-way-to-god"/>
<!-- 设置文件的当前路径 -->
<property name="LOG_PATH" value="${APP_ID}-log"/>
<!-- 控制台输入日志 -->
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<!-- debug以下的日志不输出 -->
<filter class="ch.qos.logback.classic.filter.ThresholdFilter">
<level>debug</level>
</filter>
<encoder>
<!-- 日志输出的格式 -->
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern>
<charset>UTF-8</charset>
</encoder>
</appender>
<appender name="FILE_DEBUG"
class="ch.qos.logback.core.rolling.RollingFileAppender">
<!-- 正在记录的日志文件的路径及文件名 -->
<file>${LOG_PATH}/log_debug.log</file>
<!--日志文件输出格式-->
<encoder>
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern>
<charset>UTF-8</charset> <!-- 设置字符集 -->
</encoder>
<!-- 日志记录器的滚动策略,按日期,按大小记录 -->
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<!-- 日志归档 -->
<fileNamePattern>${LOG_PATH}/debug/${APP_ID}-log-debug-%d{yyyy-MM-dd}.%i.log</fileNamePattern>
<timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
<maxFileSize>50MB</maxFileSize>
</timeBasedFileNamingAndTriggeringPolicy>
<!--日志文件保留天数-->
<maxHistory>30</maxHistory>
</rollingPolicy>
<!-- 此日志文件只记录debug级别的 -->
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<level>DEBUG</level>
<!-- 相同的则记录日志 -->
<onMatch>ACCEPT</onMatch>
<!-- 不同的则不记录日志 -->
<onMismatch>DENY</onMismatch>
</filter>
</appender>
<appender name="FILE_INFO"
class="ch.qos.logback.core.rolling.RollingFileAppender">
<!-- 正在记录的日志文件的路径及文件名 -->
<file>${LOG_PATH}/log_info.log</file>
<!--日志文件输出格式-->
<encoder>
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern>
<charset>UTF-8</charset>
</encoder>
<!-- 日志记录器的滚动策略,按日期,按大小记录 -->
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<!-- 每天日志归档路径以及格式 -->
<fileNamePattern>${LOG_PATH}/info/${APP_ID}-log-info-%d{yyyy-MM-dd}.%i.log</fileNamePattern>
<timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
<maxFileSize>50MB</maxFileSize>
</timeBasedFileNamingAndTriggeringPolicy>
<!--日志文件保留天数-->
<maxHistory>30</maxHistory>
</rollingPolicy>
<!-- 此日志文件只记录info级别的 -->
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<level>INFO</level>
<!-- 相同的则记录日志 -->
<onMatch>ACCEPT</onMatch>
<!-- 不同的则不记录日志 -->
<onMismatch>DENY</onMismatch>
</filter>
</appender>
<appender name="FILE_WARN"
class="ch.qos.logback.core.rolling.RollingFileAppender">
<!-- 正在记录的日志文件的路径及文件名 -->
<file>${LOG_PATH}/log_warn.log</file>
<!--日志文件输出格式-->
<encoder>
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern>
<charset>UTF-8</charset> <!-- 此处设置字符集 -->
</encoder>
<!-- 日志记录器的滚动策略,按日期,按大小记录 -->
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>${LOG_PATH}/warn/${APP_ID}-log-warn-%d{yyyy-MM-dd}.%i.log</fileNamePattern>
<timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
<maxFileSize>50MB</maxFileSize>
</timeBasedFileNamingAndTriggeringPolicy>
<!--日志文件保留天数-->
<maxHistory>30</maxHistory>
</rollingPolicy>
<!-- 此日志文件只记录warn级别的 -->
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<level>warn</level>
<!-- 相同的则记录日志 -->
<onMatch>ACCEPT</onMatch>
<!-- 不同的则不记录日志 -->
<onMismatch>DENY</onMismatch>
</filter>
</appender>
<appender name="FILE_ERROR"
class="ch.qos.logback.core.rolling.RollingFileAppender">
<!-- 正在记录的日志文件的路径及文件名 -->
<file>${LOG_PATH}/log_error.log</file>
<!--日志文件输出格式-->
<encoder>
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern>
<charset>UTF-8</charset> <!-- 此处设置字符集 -->
</encoder>
<!-- 日志记录器的滚动策略,按日期,按大小记录 -->
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>${LOG_PATH}/error/${APP_ID}-log-error-%d{yyyy-MM-dd}.%i.log</fileNamePattern>
<timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
<maxFileSize>50MB</maxFileSize>
</timeBasedFileNamingAndTriggeringPolicy>
<!--日志文件保留天数-->
<maxHistory>50</maxHistory>
</rollingPolicy>
<!-- 此日志文件只记录ERROR级别的 -->
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<level>ERROR</level>
<!-- 相同的则记录日志 -->
<onMatch>ACCEPT</onMatch>
<!-- 不同的则不记录日志 -->
<onMismatch>DENY</onMismatch>
</filter>
</appender>
<root level="INFO">
<!-- appender referenced after it is defined -->
<appender-ref ref="STDOUT"/>
<appender-ref ref="FILE_DEBUG" />
<appender-ref ref="FILE_INFO" />
<appender-ref ref="FILE_WARN" />
<appender-ref ref="FILE_ERROR" />
</root>
</configuration>
3、代码例子
import lombok.extern.slf4j.Slf4j;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* @author liujianming
* @version 1.0
* @describe
* @date 2022/11/2 16:39
*/
@Slf4j
@RestController
@RequestMapping("/aaa")
public class BatchInsertDemo {
@Resource
private TestMapper testMapper;
@Autowired
private SqlSessionFactory sqlSessionFactory;
public static Logger logger = LoggerFactory.getLogger(BatchInsertDemo.class);
@GetMapping("/aaa")
@ApiOperation("批处理方式")
public long aaa(int size) {
log.warn("我是批处理标签日志lombok");
logger.warn("我是批处理标签日志");
List<TestA> data1 = createData(size);
long start = System.currentTimeMillis();
SqlSession sqlSession = sqlSessionFactory.openSession(ExecutorType.BATCH, false);
TestMapper testMapper = sqlSession.getMapper(TestMapper.class);
data1.forEach(testMapper::insertOne);
sqlSession.commit();
// sqlSession.clearCache();
return System.currentTimeMillis() - start;
}
@GetMapping("/bbb")
@ApiOperation("foreach标签方式")
public long bbb(int size) {
logger.info("我是foreach标签日志");
List<TestA> data1 = createData(size);
long start = System.currentTimeMillis();
testMapper.insertBatch(data1);
return System.currentTimeMillis() - start;
}
@GetMapping("/ccc")
@ApiOperation("for循环")
public long ccc(int size) {
logger.error("我是for循环日志");
List<TestA> data1 = createData(size);
long start = System.currentTimeMillis();
for (TestA testA : data1) {
testMapper.insertOne(testA);
}
return System.currentTimeMillis() - start;
}
private List<TestA> createData(int size){
List<TestA> studentList = new ArrayList<>();
TestA student;
for(int i = 0; i < size; i++){
student = new TestA();
student.setId("小王" + i);
student.setInformationId("i" + i);
student.setIsRead("0");
student.setOrgId("orgId" + i);
student.setReadDate(new Date() + "");
student.setReadNumber("" + i);
student.setReceipt("1");
student.setUseFlag("1");
studentList.add(student);
}
return studentList;
}
}