Skip to content

Commit a3262a2

Browse files
committed
feat: 完善 plugin log
1 parent 49a8fe4 commit a3262a2

13 files changed

Lines changed: 320 additions & 246 deletions

File tree

application/src/main/java/top/cadecode/uniboot/controller/AuthController.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,10 +11,10 @@
1111
import org.springframework.web.bind.annotation.RequestParam;
1212
import org.springframework.web.bind.annotation.RestController;
1313
import top.cadecode.uniboot.common.core.annotation.ApiFormat;
14-
import top.cadecode.uniboot.common.core.annotation.ApiLogger;
15-
import top.cadecode.uniboot.common.core.enums.LogTypeEnum;
1614
import top.cadecode.uniboot.common.core.response.ApiResult;
1715
import top.cadecode.uniboot.common.core.util.JacksonUtil;
16+
import top.cadecode.uniboot.common.plugin.log.annotation.ApiLogger;
17+
import top.cadecode.uniboot.common.plugin.log.enums.LogTypeEnum;
1818
import top.cadecode.uniboot.framework.config.SecurityConfig;
1919
import top.cadecode.uniboot.framework.security.TokenAuthHolder;
2020

common/plugin/log/pom.xml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,4 +11,10 @@
1111

1212
<artifactId>uni-boot-common-plugin-log</artifactId>
1313

14+
<dependencies>
15+
<dependency>
16+
<groupId>top.cadecode</groupId>
17+
<artifactId>uni-boot-common-core</artifactId>
18+
</dependency>
19+
</dependencies>
1420
</project>

common/core/src/main/java/top/cadecode/uniboot/common/core/annotation/ApiLogger.java renamed to common/plugin/log/src/main/java/top/cadecode/uniboot/common/plugin/log/annotation/ApiLogger.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
1-
package top.cadecode.uniboot.common.core.annotation;
1+
package top.cadecode.uniboot.common.plugin.log.annotation;
22

3-
import top.cadecode.uniboot.common.core.enums.LogTypeEnum;
3+
4+
import top.cadecode.uniboot.common.plugin.log.enums.LogTypeEnum;
45

56
import java.lang.annotation.*;
67

Lines changed: 139 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,139 @@
1+
package top.cadecode.uniboot.common.plugin.log.aspect;
2+
3+
import cn.hutool.core.exceptions.ExceptionUtil;
4+
import cn.hutool.core.util.ObjectUtil;
5+
import com.dtp.core.thread.DtpExecutor;
6+
import lombok.*;
7+
import lombok.extern.slf4j.Slf4j;
8+
import org.aspectj.lang.ProceedingJoinPoint;
9+
import org.aspectj.lang.annotation.Around;
10+
import org.aspectj.lang.annotation.Aspect;
11+
import org.aspectj.lang.annotation.Pointcut;
12+
import org.aspectj.lang.reflect.MethodSignature;
13+
import org.springframework.stereotype.Component;
14+
import org.springframework.web.context.request.RequestContextHolder;
15+
import org.springframework.web.context.request.ServletRequestAttributes;
16+
import top.cadecode.uniboot.common.core.util.JacksonUtil;
17+
import top.cadecode.uniboot.common.plugin.log.annotation.ApiLogger;
18+
import top.cadecode.uniboot.common.plugin.log.handler.AbstractApiLogHandler;
19+
20+
import javax.servlet.http.HttpServletRequest;
21+
22+
/**
23+
* 请求响应信息日志 AOP 类
24+
*
25+
* @author Cade Li
26+
* @date 2021/12/4
27+
*/
28+
@Slf4j
29+
@RequiredArgsConstructor
30+
@Aspect
31+
@Component
32+
public class ApiLoggerAspect {
33+
34+
private final DtpExecutor asyncExecutor;
35+
36+
private final AbstractApiLogHandler apiLogHandler;
37+
38+
@Pointcut("@within(top.cadecode.uniboot.common.plugin.log.annotation.ApiLogger) " +
39+
"|| @annotation(top.cadecode.uniboot.common.plugin.log.annotation.ApiLogger)")
40+
public void pointCut() {
41+
42+
}
43+
44+
/**
45+
* 环绕通知
46+
*
47+
* @param point 切入点
48+
* @return 原方法返回值
49+
* @throws Throwable 异常信息
50+
*/
51+
@Around("pointCut()")
52+
public Object around(ProceedingJoinPoint point) throws Throwable {
53+
// 根据注解判断是否开启
54+
ApiLogger apiLogger = getApiLogger(point);
55+
if (!apiLogger.value()) {
56+
return point.proceed();
57+
}
58+
// 统计耗时
59+
long startTime = System.currentTimeMillis();
60+
Object result = null;
61+
Throwable throwable = null;
62+
try {
63+
result = point.proceed();
64+
return result;
65+
} catch (Throwable e) {
66+
throwable = e;
67+
throw e;
68+
} finally {
69+
handleLogger(point, apiLogger, result, throwable, System.currentTimeMillis() - startTime);
70+
}
71+
}
72+
73+
/**
74+
* 获取 ApiLogger 注解
75+
*/
76+
private ApiLogger getApiLogger(ProceedingJoinPoint point) {
77+
MethodSignature methodSignature = (MethodSignature) point.getSignature();
78+
ApiLogger apiLogger = methodSignature.getMethod().getAnnotation(ApiLogger.class);
79+
if (apiLogger == null) {
80+
apiLogger = methodSignature.getMethod()
81+
.getDeclaringClass()
82+
.getAnnotation(ApiLogger.class);
83+
}
84+
return apiLogger;
85+
}
86+
87+
/**
88+
* 获取请求、结果、异常等信息,构造日志
89+
*/
90+
public void handleLogger(ProceedingJoinPoint point, ApiLogger apiLogger, Object result, Throwable throwable, Long timeCost) {
91+
// 解析请求对象
92+
ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
93+
if (ObjectUtil.isNull(attributes)) {
94+
return;
95+
}
96+
try {
97+
String resultStr = null;
98+
boolean exceptional = false;
99+
if (ObjectUtil.isNotNull(throwable)) {
100+
exceptional = true;
101+
resultStr = ExceptionUtil.stacktraceToString(throwable);
102+
} else {
103+
try {
104+
resultStr = JacksonUtil.toJson(result);
105+
} catch (Exception e) {
106+
resultStr = ExceptionUtil.stacktraceToString(e);
107+
log.warn("API log [{}]: request result to json fail", apiLogger.type().getType(), e);
108+
}
109+
}
110+
BaseLogInfo baseLogInfo = BaseLogInfo.builder().apiLogger(apiLogger).request(attributes.getRequest())
111+
.resultStr(resultStr).timeCost(timeCost).exceptional(exceptional).build();
112+
Object logObj = apiLogHandler.generateLog(point, baseLogInfo);
113+
// 打印日志
114+
log.info("API log [{}]: {}", apiLogger.type().getType(), JacksonUtil.toJson(logObj));
115+
// 持久化 异步
116+
asyncExecutor.execute(() -> {
117+
try {
118+
apiLogHandler.save(apiLogger, logObj);
119+
} catch (Exception e) {
120+
log.warn("API log [{}]: save async fail", apiLogger.type().getType(), e);
121+
}
122+
});
123+
} catch (Exception e) {
124+
log.warn("API log [{}]: handle logger fail", apiLogger.type().getType(), e);
125+
}
126+
}
127+
128+
@Data
129+
@AllArgsConstructor
130+
@NoArgsConstructor
131+
@Builder
132+
public static class BaseLogInfo {
133+
private ApiLogger apiLogger;
134+
private Boolean exceptional;
135+
private HttpServletRequest request;
136+
private String resultStr;
137+
private Long timeCost;
138+
}
139+
}

common/core/src/main/java/top/cadecode/uniboot/common/core/enums/LogTypeEnum.java renamed to common/plugin/log/src/main/java/top/cadecode/uniboot/common/plugin/log/enums/LogTypeEnum.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
package top.cadecode.uniboot.common.core.enums;
1+
package top.cadecode.uniboot.common.plugin.log.enums;
22

33
import com.baomidou.mybatisplus.annotation.EnumValue;
44
import com.fasterxml.jackson.annotation.JsonValue;
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
package top.cadecode.uniboot.common.plugin.log.handler;
2+
3+
import lombok.extern.slf4j.Slf4j;
4+
import org.aspectj.lang.JoinPoint;
5+
import org.aspectj.lang.ProceedingJoinPoint;
6+
import org.aspectj.lang.Signature;
7+
import org.aspectj.lang.reflect.MethodSignature;
8+
import org.springframework.util.ObjectUtils;
9+
import org.springframework.web.multipart.MultipartFile;
10+
import top.cadecode.uniboot.common.plugin.log.annotation.ApiLogger;
11+
import top.cadecode.uniboot.common.plugin.log.aspect.ApiLoggerAspect.BaseLogInfo;
12+
13+
import javax.servlet.http.HttpServletRequest;
14+
import javax.servlet.http.HttpServletResponse;
15+
import java.util.Collections;
16+
import java.util.HashMap;
17+
import java.util.Map;
18+
19+
/**
20+
* Api Log 处理器抽象
21+
*
22+
* @author Cade Li
23+
* @since 2023/6/8
24+
*/
25+
@Slf4j
26+
public abstract class AbstractApiLogHandler {
27+
28+
public abstract Object generateLog(ProceedingJoinPoint point, BaseLogInfo baseLogInfo);
29+
30+
public abstract void save(ApiLogger apiLogger, Object o);
31+
32+
/**
33+
* 获取方法参数名和参数值
34+
*/
35+
public static Map<String, Object> getRequestParams(JoinPoint joinPoint, ApiLogger apiLogger) {
36+
Signature signature = joinPoint.getSignature();
37+
MethodSignature methodSignature = (MethodSignature) signature;
38+
String[] names = methodSignature.getParameterNames();
39+
Object[] args = joinPoint.getArgs();
40+
if (ObjectUtils.isEmpty(names) || ObjectUtils.isEmpty(args)) {
41+
return Collections.emptyMap();
42+
}
43+
if (names.length != args.length) {
44+
log.warn("API log [{}]: method [{}] param and the pass value do not match", apiLogger.type().getType(), methodSignature.getName());
45+
return Collections.emptyMap();
46+
}
47+
Map<String, Object> map = new HashMap<>();
48+
for (int i = 0; i < names.length; i++) {
49+
// 排除请求对象和响应
50+
if (args[i] instanceof HttpServletRequest || args[i] instanceof HttpServletResponse) {
51+
continue;
52+
}
53+
// 处理 MultipartFile
54+
if (args[i] instanceof MultipartFile) {
55+
map.put(names[i], ((MultipartFile) args[i]).getOriginalFilename());
56+
continue;
57+
}
58+
map.put(names[i], args[i]);
59+
}
60+
return map;
61+
}
62+
}

framework/pom.xml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,5 +21,9 @@
2121
<groupId>top.cadecode</groupId>
2222
<artifactId>uni-boot-common-plugin-swagger</artifactId>
2323
</dependency>
24+
<dependency>
25+
<groupId>top.cadecode</groupId>
26+
<artifactId>uni-boot-common-plugin-log</artifactId>
27+
</dependency>
2428
</dependencies>
2529
</project>

0 commit comments

Comments
 (0)