1、引入pom文件
<dependency> <groupId>org.springframework</groupId> <artifactId>spring-aspects</artifactId> </dependency> <dependency> <groupId>com.alibaba</groupId> <artifactId>fastjson</artifactId> <version>1.2.75</version> </dependency>
2、定义工具类
public class HttpContextUtils { public static HttpServletRequest getHttpServletRequest() { return ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest(); } }
public class IPUtils { private static Logger logger = LoggerFactory.getLogger(IPUtils.class); /** * 获取IP地址 * 使用Nginx等反向代理软件, 则不能通过request.getRemoteAddr()获取IP地址 * 如果使用了多级反向代理的话,X-Forwarded-For的值并不止一个,而是一串IP地址,X-Forwarded-For中第一个非unknown的有效IP字符串,则为真实IP地址 */ public static String getIpAddr(HttpServletRequest request) { String ip = null; try { ip = request.getHeader("x-forwarded-for"); if (StringUtils.isEmpty(ip) || "unknown".equalsIgnoreCase(ip)) { ip = request.getHeader("Proxy-Client-IP"); } if (StringUtils.isEmpty(ip) || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) { ip = request.getHeader("WL-Proxy-Client-IP"); } if (StringUtils.isEmpty(ip) || "unknown".equalsIgnoreCase(ip)) { ip = request.getHeader("HTTP_CLIENT_IP"); } if (StringUtils.isEmpty(ip) || "unknown".equalsIgnoreCase(ip)) { ip = request.getHeader("HTTP_X_FORWARDED_FOR"); } if (StringUtils.isEmpty(ip) || "unknown".equalsIgnoreCase(ip)) { ip = request.getRemoteAddr(); } } catch (Exception e) { logger.error("IPUtils ERROR ", e); } // 使用代理,则获取第一个IP地址 if (StringUtils.isEmpty(ip) && ip.length() > 15) { if (ip.indexOf(",") > 0) { ip = ip.substring(0, ip.indexOf(",")); } } return ip; } }
3、创建注解
@Target(ElementType.METHOD) @Retention(RetentionPolicy.RUNTIME) @Documented public @interface LogAnnotation { String module() default ""; String operator() default ""; }
4、定义切面
@Slf4j @Aspect @Component public class LogAspect { @Pointcut(value = "@annotation(com.example.demo.aop.LogAnnotation)") public void pt() { } //环绕通知 @Around("pt()") public Object log(ProceedingJoinPoint joinPoint) throws Throwable { long startTime = System.currentTimeMillis(); //执行方法 Object result = joinPoint.proceed(); //执行时长 long time = System.currentTimeMillis() - startTime; //保存日志 recordLog(joinPoint, time); return result; } private void recordLog(ProceedingJoinPoint joinPoint, long time) { MethodSignature signature = (MethodSignature) joinPoint.getSignature(); Method method = signature.getMethod(); LogAnnotation logAnnotation = method.getAnnotation(LogAnnotation.class); log.info("============log start=========="); log.info("module:{}", logAnnotation.module()); log.info("operator:{}", logAnnotation.operator()); //请求的方法名 String className = joinPoint.getTarget().getClass().getName(); String methodName = signature.getName(); log.info("request method:{}", className + "." + methodName + "()"); //请求的参数 Object[] args = joinPoint.getArgs(); String params = JSON.toJSONString(args[0]); log.info("params:{}", params); //获取request 设置IP地址 HttpServletRequest request = HttpContextUtils.getHttpServletRequest(); log.info("ip:{}", IPUtils.getIpAddr(request)); log.info("excute time: {} ms", time); log.info("==============log end============="); } }
5、写测试方法
@GetMapping(value = "/test") @LogAnnotation(module = "方法", operator = "测试方法") public void test(String test) { log.info("test方法执行了 入参为:{}", test); }
6、执行url:
http://localhost:8081/test?test=param
执行结果:
:test方法执行了入参为:param .307:============logstart========== .307:module:方法 .307:operator:测试方法 .307:requestmethod:com.example.demo.controller.HomeController.test() .368:params:"param" .369:ip:0:0:0:0:0:0:0:1 .370:excutetime:5844ms .370:==============logend=============