package com.xxx.xxx.aop;
import com.alibaba.fastjson.JSON;
import com.google.common.base.Stopwatch;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
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 javax.servlet.http.HttpServletResponse;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;
/**
* @description:
* @author: zhanglao
* @date: 2022/3/25 7:24 下午
*/
@Component
@Aspect
@Slf4j
public class RequestAop{
/**
* @Description: 定义需要拦截的切面
* @Pointcut("execution(* com.*.controller.*Controller.*(..))")
* @Return: void
**/
@Pointcut("execution(* com.xxxx.facade.controller.*Controller.*(..))")
public void executeController() {
}
@Around("executeController()")
public Objectinvoke(ProceedingJoinPoint joinPoint) throws Throwable{
Object result;
Stopwatch stopwatch = Stopwatch.createStarted();
result = joinPoint.proceed();
try {
HttpServletRequest request =((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
// ip地址
String ipAddr = getRemoteHost(request);
// 请求路径
String requestUrl = request.getRequestURL().toString();
// 获取请求参数进行打印
Signature signature = joinPoint.getSignature();
MethodSignature methodSignature =(MethodSignature) signature;
// 类名
// swagger中文注释名
String classCommentName = methodSignature.getMethod().getDeclaringClass().getAnnotation(Api.class).tags()[0];
String[] sourceName = signature.getDeclaringTypeName().split("\\.");
String className = sourceName[sourceName.length -1] +"[" + classCommentName +"]";
// 方法名
// swagger中文注释名
String methodCommentName = methodSignature.getMethod().getAnnotation(ApiOperation.class).value();
String methodName = signature.getName() +"[" + methodCommentName +"]";
// 参数名数组
String[] parameterNames =((MethodSignature) signature).getParameterNames();
// 构造参数组集合
List<Object> argList =new ArrayList<>();
for (Object arg : joinPoint.getArgs()) {
// request/response无法使用toJSON
if (arginstanceof HttpServletRequest) {
argList.add("request");
} else if (arginstanceof HttpServletResponse) {
argList.add("response");
} else {
argList.add(JSON.toJSON(arg));
}
}
stopwatch.stop();
long timeConsuming = stopwatch.elapsed(TimeUnit.MILLISECONDS);
log.error("请求源IP【{}】 -> 请求URL【{}】\n{} -> {} -> 请求耗时:[{}]毫秒 \n请求参数:{} -> {}\n请求结果:{}",
ipAddr, requestUrl,
className, methodName, timeConsuming,
JSON.toJSON(parameterNames), JSON.toJSON(argList),
JSON.toJSON(result));
} catch (Exception e) {
log.error("参数获取失败: {}", e.getMessage());
}
return result;
}
/**
* 获取目标主机的ip
* @param request
* @return
*/
private StringgetRemoteHost(HttpServletRequest request) {
String ip = request.getHeader("x-forwarded-for");
if (ip ==null || ip.length() ==0 ||"unknown".equalsIgnoreCase(ip)) {
ip = request.getHeader("Proxy-Client-IP");
}
if (ip ==null || ip.length() ==0 ||"unknown".equalsIgnoreCase(ip)) {
ip = request.getHeader("WL-Proxy-Client-IP");
}
if (ip ==null || ip.length() ==0 ||"unknown".equalsIgnoreCase(ip)) {
ip = request.getRemoteAddr();
}
return ip.contains("0:0:0:0:0:0:0:1") ?"127.0.0.1" : ip;
}
}
AOP拦截请求获取请求信息记录日志
©著作权归作者所有,转载或内容合作请联系作者
- 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
- 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
- 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
推荐阅读更多精彩内容
- 一:功能简介 本文主要记录如何使用aop切面的方式来实现日志记录功能。 主要记录的信息有: 操作人,方法名,参数,...
- 前言 在实际的项目中,特别是管理系统中,对于那些重要的操作我们通常都会记录操作日志。比如对数据库的CRUD操作,我...
- 前言:之前发的文章评论中,很多小伙伴说希望我写一篇关于Spring Boot + validation + AOP...