一、添加依赖
项目添加log4j2依赖(需要排除Logback依赖),添加aop依赖
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.2.1.RELEASE</version>
<relativePath/>
</parent>
<groupId>com.learn</groupId>
<artifactId>mall</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>mall</name>
<description>mall project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<exclusions>
<!--添加log4j2依赖时需要排除Logback依赖-->
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-logging</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<!--添加mybatis依赖-->
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>1.3.2</version>
</dependency>
<!--添加MySQL依赖-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<!--添加log4j2依赖-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-log4j2</artifactId>
</dependency>
<!--添加aop依赖-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
<!--添加mybatis逆向工程插件-->
<plugin>
<groupId>org.mybatis.generator</groupId>
<artifactId>mybatis-generator-maven-plugin</artifactId>
<version>1.3.7</version>
<configuration>
<verbose>true</verbose>
<overwrite>true</overwrite>
</configuration>
</plugin>
</plugins>
</build>
</project>
二、编写log4j2.xml文件
编写log4j2.xml文件并放于resources目录下
<?xml version="1.0" encoding="UTF-8"?>
<configuration status = "fatal">
<properties>
<!--指定日志目录-->
<Property name="baseDir" value="D:\项目代码\spring-boot学习项目\logs"/>
</properties>
<appenders>
<Console name="Console" target="SYSTEM_OUT">
<!--控制台只输出level及以上级别的信息(onMatch),其他的直接拒绝(onMismatch)-->
<ThresholdFilter level="info" onMatch="ACCEPT" onMismatch="DENY"/>
<PatternLayout pattern="[%d{MM:dd HH:mm:ss.SSS}] [%level] [%logger{36}] - %msg%n"/>
</Console>
<!--debug级别日志文件输出-->
<RollingFile name="debug_appender" fileName="${baseDir}/debug.log" filePattern="${baseDir}/debug_%i.log.%d{yyyy-MM-dd}">
<!--过滤器-->
<Filters>
<!--限制日志级别再debug及以上,在info以下-->
<ThresholdFilter level="debug"/>
<ThresholdFilter level="info" onMatch="DENY" onMismatch="NEUTRAL"/>
</Filters>
<!--日志格式-->
<PatternLayout pattern="[%d{HH:mm:ss:SSS}] [%p] - %l - %m%n"/>
<!--策略-->
<Policies>
<!--每隔一天转存-->
<TimeBasedTriggeringPolicy interval="1" modulate="true"/>
<!--文件大小-->
<SizeBasedTriggeringPolicy size="100 MB"/>
</Policies>
</RollingFile>
<!--info级别日志文件输出-->
<RollingFile name="info_appender" fileName="${baseDir}/info.log" filePattern="${baseDir}/info_%i.log.%d{yyyy-MM-dd}">
<!--过滤器-->
<Filters>
<!--限制日志级别再info及以上,在error以下-->
<ThresholdFilter level="info"/>
<ThresholdFilter level="error" onMatch="DENY" onMismatch="NEUTRAL"/>
</Filters>
<!--日志格式-->
<PatternLayout pattern="[%d{HH:mm:ss:SSS}] [%p] - %l - %m%n"/>
<!--策略-->
<Policies>
<!--每隔一天转存-->
<TimeBasedTriggeringPolicy interval="1" modulate="true"/>
<!--文件大小-->
<SizeBasedTriggeringPolicy size="100 MB"/>
</Policies>
</RollingFile>
<!--error级别日志文件输出-->
<RollingFile name="error_appender" fileName="${baseDir}/error.log" filePattern="${baseDir}/error_%i.log.%d{yyyy-MM-dd}">
<!--过滤器-->
<Filters>
<!--限制日志级别再error及以上-->
<ThresholdFilter level="error"/>
</Filters>
<!--日志格式-->
<PatternLayout pattern="[%d{HH:mm:ss:SSS}] [%p] - %l - %m%n"/>
<!--策略-->
<Policies>
<!--每隔一天转存-->
<TimeBasedTriggeringPolicy interval="1" modulate="true"/>
<!--文件大小-->
<SizeBasedTriggeringPolicy size="100 MB"/>
</Policies>
</RollingFile>
</appenders>
<loggers>
<Root level="debug">
<AppenderRef ref="Console"/>
<AppenderRef ref="debug_appender"/>
<AppenderRef ref="info_appender"/>
<AppenderRef ref="error_appender"/>
</Root>
</loggers>
</configuration>
三、编写aop日志拦截器
package com.learn.mall.filter;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import javax.servlet.http.HttpServletRequest;
import java.util.Arrays;
/**
* AOP日志拦截器,打印请求和响应信息
*/
@Aspect
@Component
public class WebLogAspect {
private final Logger log = LoggerFactory.getLogger(WebLogAspect.class);
@Pointcut("execution(public * com.learn.mall.controller.*.*(..))")
public void webLog(){
}
/**
* 收到请求,记录请求内容
* @param joinPoint
*/
@Before("webLog()")
public void doBefore(JoinPoint joinPoint){
ServletRequestAttributes attributes = (ServletRequestAttributes)RequestContextHolder.getRequestAttributes();
HttpServletRequest request = attributes.getRequest();
log.info("URL:"+request.getRequestURI().toString());
log.info("HTTP_METHOD:"+request.getMethod());
log.info("IP:"+request.getRemoteAddr());
log.info("CLASS_METHOD:"+joinPoint.getSignature().getDeclaringTypeName()+"."+joinPoint.getSignature().getName());
log.info("ARGS:"+Arrays.toString(joinPoint.getArgs()));
}
/**
* 处理完请求,返回内容
* @param res
*/
@AfterReturning(returning = "res",pointcut = "webLog()")
public void doAfterReturning(Object res) throws JsonProcessingException {
log.info("RESPONSE:"+new ObjectMapper().writeValueAsString(res));
}
}