diff --git a/spring-boot-demo-log-aop/.gitignore b/spring-boot-demo-log-aop/.gitignore new file mode 100644 index 0000000..82eca33 --- /dev/null +++ b/spring-boot-demo-log-aop/.gitignore @@ -0,0 +1,25 @@ +/target/ +!.mvn/wrapper/maven-wrapper.jar + +### STS ### +.apt_generated +.classpath +.factorypath +.project +.settings +.springBeans +.sts4-cache + +### IntelliJ IDEA ### +.idea +*.iws +*.iml +*.ipr + +### NetBeans ### +/nbproject/private/ +/build/ +/nbbuild/ +/dist/ +/nbdist/ +/.nb-gradle/ \ No newline at end of file diff --git a/spring-boot-demo-log-aop/README.md b/spring-boot-demo-log-aop/README.md new file mode 100644 index 0000000..8908633 --- /dev/null +++ b/spring-boot-demo-log-aop/README.md @@ -0,0 +1,201 @@ +# spring-boot-demo-log-aop + +> 此 demo 主要是演示如何使用 aop 切面对请求进行日志记录,并且记录 UserAgent 信息。 + +## pom.xml + +```xml + + + 4.0.0 + + com.xkcoding + spring-boot-demo-log-aop + 0.0.1-SNAPSHOT + jar + + spring-boot-demo-log-aop + Demo project for Spring Boot + + + org.springframework.boot + spring-boot-starter-parent + 2.0.5.RELEASE + + + + + UTF-8 + UTF-8 + 1.8 + 4.1.14 + 1.20 + + + + + org.springframework.boot + spring-boot-starter-web + + + + org.springframework.boot + spring-boot-starter-aop + + + + org.springframework.boot + spring-boot-starter-test + test + + + + org.projectlombok + lombok + + + + cn.hutool + hutool-all + ${hutool.version} + + + + + eu.bitwalker + UserAgentUtils + ${user.agent.version} + + + + + spring-boot-demo-log-aop + + + org.springframework.boot + spring-boot-maven-plugin + + + + + +``` + +## AopLog.java + +```java +/** + *

+ * 使用 aop 切面记录请求日志信息 + *

+ * + * @package: com.xkcoding.log.aop.aspectj + * @description: 使用 aop 切面记录请求日志信息 + * @author: yangkai.shen + * @date: Created in 2018/10/1 10:05 PM + * @copyright: Copyright (c) 2018 + * @version: V1.0 + * @modified: yangkai.shen + */ +@Aspect +@Component +@Slf4j +public class AopLog { + private static final String START_TIME = "request-start"; + + /** + * 切入点 + */ + @Pointcut("execution(public * com.xkcoding.log.aop.controller.*Controller.*(..))") + public void log() { + + } + + /** + * 前置操作 + * + * @param point 切入点 + */ + @Before("log()") + public void beforeLog(JoinPoint point) { + ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes(); + + HttpServletRequest request = Objects.requireNonNull(attributes).getRequest(); + + log.info("【请求 URL】:{}", request.getRequestURL()); + log.info("【请求 IP】:{}", request.getRemoteAddr()); + log.info("【请求类名】:{},【请求方法名】:{}", point.getSignature().getDeclaringTypeName(), point.getSignature().getName()); + + Map parameterMap = request.getParameterMap(); + log.info("【请求参数】:{},", JSONUtil.toJsonStr(parameterMap)); + Long start = System.currentTimeMillis(); + request.setAttribute(START_TIME, start); + } + + /** + * 环绕操作 + * + * @param point 切入点 + * @return 原方法返回值 + * @throws Throwable 异常信息 + */ + @Around("log()") + public Object aroundLog(ProceedingJoinPoint point) throws Throwable { + Object result = point.proceed(); + log.info("【返回值】:{}", JSONUtil.toJsonStr(result)); + return result; + } + + /** + * 后置操作 + */ + @AfterReturning("log()") + public void afterReturning() { + ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes(); + HttpServletRequest request = Objects.requireNonNull(attributes).getRequest(); + + Long start = (Long) request.getAttribute(START_TIME); + Long end = System.currentTimeMillis(); + log.info("【请求耗时】:{}毫秒", end - start); + + String header = request.getHeader("User-Agent"); + UserAgent userAgent = UserAgent.parseUserAgentString(header); + log.info("【浏览器类型】:{},【操作系统】:{},【原始User-Agent】:{}", userAgent.getBrowser().toString(), userAgent.getOperatingSystem().toString(), header); + } +} +``` + +## TestController.java + +```java +/** + *

+ * 测试 Controller + *

+ * + * @package: com.xkcoding.log.aop.controller + * @description: 测试 Controller + * @author: yangkai.shen + * @date: Created in 2018/10/1 10:10 PM + * @copyright: Copyright (c) 2018 + * @version: V1.0 + * @modified: yangkai.shen + */ +@RestController +public class TestController { + + /** + * 测试方法 + * + * @param who 测试参数 + * @return {@link Dict} + */ + @GetMapping("/test") + public Dict test(String who) { + return Dict.create().set("who", StrUtil.isBlank(who) ? "me" : who); + } + +} +``` + diff --git a/spring-boot-demo-log-aop/pom.xml b/spring-boot-demo-log-aop/pom.xml new file mode 100644 index 0000000..d2b07a3 --- /dev/null +++ b/spring-boot-demo-log-aop/pom.xml @@ -0,0 +1,75 @@ + + + 4.0.0 + + com.xkcoding + spring-boot-demo-log-aop + 0.0.1-SNAPSHOT + jar + + spring-boot-demo-log-aop + Demo project for Spring Boot + + + org.springframework.boot + spring-boot-starter-parent + 2.0.5.RELEASE + + + + + UTF-8 + UTF-8 + 1.8 + 4.1.14 + 1.20 + + + + + org.springframework.boot + spring-boot-starter-web + + + + org.springframework.boot + spring-boot-starter-aop + + + + org.springframework.boot + spring-boot-starter-test + test + + + + org.projectlombok + lombok + + + + cn.hutool + hutool-all + ${hutool.version} + + + + + eu.bitwalker + UserAgentUtils + ${user.agent.version} + + + + + spring-boot-demo-log-aop + + + org.springframework.boot + spring-boot-maven-plugin + + + + + diff --git a/spring-boot-demo-log-aop/src/main/java/com/xkcoding/log/aop/SpringBootDemoLogAopApplication.java b/spring-boot-demo-log-aop/src/main/java/com/xkcoding/log/aop/SpringBootDemoLogAopApplication.java new file mode 100644 index 0000000..8240bcc --- /dev/null +++ b/spring-boot-demo-log-aop/src/main/java/com/xkcoding/log/aop/SpringBootDemoLogAopApplication.java @@ -0,0 +1,25 @@ +package com.xkcoding.log.aop; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +/** + *

+ * 启动类 + *

+ * + * @package: com.xkcoding.log.aop + * @description: 启动类 + * @author: yangkai.shen + * @date: Created in 2018/10/1 10:05 PM + * @copyright: Copyright (c) 2018 + * @version: V1.0 + * @modified: yangkai.shen + */ +@SpringBootApplication +public class SpringBootDemoLogAopApplication { + + public static void main(String[] args) { + SpringApplication.run(SpringBootDemoLogAopApplication.class, args); + } +} diff --git a/spring-boot-demo-log-aop/src/main/java/com/xkcoding/log/aop/aspectj/AopLog.java b/spring-boot-demo-log-aop/src/main/java/com/xkcoding/log/aop/aspectj/AopLog.java new file mode 100644 index 0000000..9caa858 --- /dev/null +++ b/spring-boot-demo-log-aop/src/main/java/com/xkcoding/log/aop/aspectj/AopLog.java @@ -0,0 +1,95 @@ +package com.xkcoding.log.aop.aspectj; + +import cn.hutool.json.JSONUtil; +import eu.bitwalker.useragentutils.UserAgent; +import lombok.extern.slf4j.Slf4j; +import org.aspectj.lang.JoinPoint; +import org.aspectj.lang.ProceedingJoinPoint; +import org.aspectj.lang.annotation.*; +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.Map; +import java.util.Objects; + +/** + *

+ * 使用 aop 切面记录请求日志信息 + *

+ * + * @package: com.xkcoding.log.aop.aspectj + * @description: 使用 aop 切面记录请求日志信息 + * @author: yangkai.shen + * @date: Created in 2018/10/1 10:05 PM + * @copyright: Copyright (c) 2018 + * @version: V1.0 + * @modified: yangkai.shen + */ +@Aspect +@Component +@Slf4j +public class AopLog { + private static final String START_TIME = "request-start"; + + /** + * 切入点 + */ + @Pointcut("execution(public * com.xkcoding.log.aop.controller.*Controller.*(..))") + public void log() { + + } + + /** + * 前置操作 + * + * @param point 切入点 + */ + @Before("log()") + public void beforeLog(JoinPoint point) { + ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes(); + + HttpServletRequest request = Objects.requireNonNull(attributes).getRequest(); + + log.info("【请求 URL】:{}", request.getRequestURL()); + log.info("【请求 IP】:{}", request.getRemoteAddr()); + log.info("【请求类名】:{},【请求方法名】:{}", point.getSignature().getDeclaringTypeName(), point.getSignature().getName()); + + Map parameterMap = request.getParameterMap(); + log.info("【请求参数】:{},", JSONUtil.toJsonStr(parameterMap)); + Long start = System.currentTimeMillis(); + request.setAttribute(START_TIME, start); + } + + /** + * 环绕操作 + * + * @param point 切入点 + * @return 原方法返回值 + * @throws Throwable 异常信息 + */ + @Around("log()") + public Object aroundLog(ProceedingJoinPoint point) throws Throwable { + Object result = point.proceed(); + log.info("【返回值】:{}", JSONUtil.toJsonStr(result)); + return result; + } + + /** + * 后置操作 + */ + @AfterReturning("log()") + public void afterReturning() { + ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes(); + HttpServletRequest request = Objects.requireNonNull(attributes).getRequest(); + + Long start = (Long) request.getAttribute(START_TIME); + Long end = System.currentTimeMillis(); + log.info("【请求耗时】:{}毫秒", end - start); + + String header = request.getHeader("User-Agent"); + UserAgent userAgent = UserAgent.parseUserAgentString(header); + log.info("【浏览器类型】:{},【操作系统】:{},【原始User-Agent】:{}", userAgent.getBrowser().toString(), userAgent.getOperatingSystem().toString(), header); + } +} diff --git a/spring-boot-demo-log-aop/src/main/java/com/xkcoding/log/aop/controller/TestController.java b/spring-boot-demo-log-aop/src/main/java/com/xkcoding/log/aop/controller/TestController.java new file mode 100644 index 0000000..8cff8c4 --- /dev/null +++ b/spring-boot-demo-log-aop/src/main/java/com/xkcoding/log/aop/controller/TestController.java @@ -0,0 +1,35 @@ +package com.xkcoding.log.aop.controller; + +import cn.hutool.core.lang.Dict; +import cn.hutool.core.util.StrUtil; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + *

+ * 测试 Controller + *

+ * + * @package: com.xkcoding.log.aop.controller + * @description: 测试 Controller + * @author: yangkai.shen + * @date: Created in 2018/10/1 10:10 PM + * @copyright: Copyright (c) 2018 + * @version: V1.0 + * @modified: yangkai.shen + */ +@RestController +public class TestController { + + /** + * 测试方法 + * + * @param who 测试参数 + * @return {@link Dict} + */ + @GetMapping("/test") + public Dict test(String who) { + return Dict.create().set("who", StrUtil.isBlank(who) ? "me" : who); + } + +} diff --git a/spring-boot-demo-log-aop/src/main/resources/application.yml b/spring-boot-demo-log-aop/src/main/resources/application.yml new file mode 100644 index 0000000..af5002c --- /dev/null +++ b/spring-boot-demo-log-aop/src/main/resources/application.yml @@ -0,0 +1,4 @@ +server: + port: 8080 + servlet: + context-path: /demo diff --git a/spring-boot-demo-log-aop/src/main/resources/logback-spring.xml b/spring-boot-demo-log-aop/src/main/resources/logback-spring.xml new file mode 100644 index 0000000..284bb16 --- /dev/null +++ b/spring-boot-demo-log-aop/src/main/resources/logback-spring.xml @@ -0,0 +1,77 @@ + + + + + + INFO + + + %date [%thread] %-5level [%logger{50}] %file:%line - %msg%n + UTF-8 + + + + + + + + ERROR + + DENY + + ACCEPT + + + + + + + logs/spring-boot-demo-log-aop/info.created_on_%d{yyyy-MM-dd}.part_%i.log + + 90 + + + + + 2MB + + + + + + + %date [%thread] %-5level [%logger{50}] %file:%line - %msg%n + UTF-8 + + + + + + + Error + + + + + + + logs/spring-boot-demo-log-aop/error.created_on_%d{yyyy-MM-dd}.part_%i.log + + 90 + + + 2MB + + + + %date [%thread] %-5level [%logger{50}] %file:%line - %msg%n + UTF-8 + + + + + + + + + \ No newline at end of file diff --git a/spring-boot-demo-log-aop/src/test/java/com/xkcoding/log/aop/SpringBootDemoLogAopApplicationTests.java b/spring-boot-demo-log-aop/src/test/java/com/xkcoding/log/aop/SpringBootDemoLogAopApplicationTests.java new file mode 100644 index 0000000..f2af7df --- /dev/null +++ b/spring-boot-demo-log-aop/src/test/java/com/xkcoding/log/aop/SpringBootDemoLogAopApplicationTests.java @@ -0,0 +1,16 @@ +package com.xkcoding.log.aop; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.junit4.SpringRunner; + +@RunWith(SpringRunner.class) +@SpringBootTest +public class SpringBootDemoLogAopApplicationTests { + + @Test + public void contextLoads() { + } + +}