AOP打印日志
大约 1 分钟
AOP打印日志
需求分析
在SpringBoot中使用自定义注解、aop切面打印web请求日志。主要是想把controller的每个request请求日志收集起来,调用接口、执行时间、返回值这几个重要的信息存储到数据库里,然后可以使用火焰图统计接口调用时长,平均响应时长,以便于我们对接口的调用和执行情况及时掌握。
解决方案:
- 使用AOP的环绕通知(around)进行方法进行增强
- 使用自定义注解用来标注那些方法需要增强(非表达式)
1️⃣ 定义自定义 @Log 注解
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Log {
String value() default "";
}
2️⃣ AOP记录操作日志
- 定义通知类并且书写环绕通知
execution:用于匹配方法执行的连接点
- 如:execution(public * com...UserService.find*(*))
@annotation:用于匹配当前执行方法持有指定注解的方法;
- 如:@annotation(com.yangeit.common.annotation.Log)
/**
* AOP 记录用户操作日志
*/
@Slf4j
@Aspect
@Component
public class LogAspect {
@Pointcut("@annotation(com.yangeit.common.annotation.Log)")
public void pointcut() {
// do nothing
}
@Around("pointcut()")
public Object around(ProceedingJoinPoint point) throws JsonProcessingException {
Object result = null;
long beginTime = System.currentTimeMillis();
try {
// 执行方法
result = point.proceed();
} catch (Throwable e) {
log.error(e.getMessage());
}
// 获取 request
HttpServletRequest request = HttpContextUtil.getHttpServletRequest();
// 设置 IP 地址
String ip = IPUtil.getIpAddr(request);
// 执行时长(毫秒)
long time = System.currentTimeMillis() - beginTime;
// 通过域对象获取用户名,然后将上述信息存入到数据中
return result;
}
}
将用户名、操作ip、操作时长记录到数据库中
3. 具体使用
- 在需要的方法上添加Log注解
@Log("新增用户")
@PostMapping
public void addUser(User user) {
....
}