目的:
通过自定义注解,在需要监控接口调用输出日志的类或方法上,加上自定义注解,实现无侵入式接口监控。
实现:
idea结构
1、导入pom
<dependency><groupId>org.aspectj</groupId><artifactId>aspectjweaver</artifactId><version>1.9.4</version>
</dependency>
2、自定义注解
ApiLog
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface ApiLog {String value() default "";
}
3、切面监控
ApiLogAspect
/*** @Author xpf* @Date 2024/6/28 14:11* @Version 1.0*/
@Aspect
@Component
@Slf4j
public class ApiLogAspect {@Pointcut("@within(com.xpf.annotion.ApiLog)")public void pointcut() {}@Around("pointcut()")public Object around(ProceedingJoinPoint point){Object result = null;long start = System.currentTimeMillis();// 获取请求URLString url = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest().getRequestURL().toString();String param = getParam(point);try {// 获取响应result = point.proceed();// 保存日志System.out.println("正常日志:"+point+","+start+","+param+","+JSONObject.toJSONString(result)+","+url);
// saveLog(point, start, param, JSONObject.toJSONString(result), url, 0);} catch (Throwable e) {//请在controller中做好拦截log.error("对外暴露接口非受检异常:" + e.getMessage(), e);System.out.println("异常日志:"+ point + start + param + e.getMessage() + url );
// saveLog(point, start, param,e.getMessage(), url,1);throw new RuntimeException("服务器异常");}return result;}private static String getParam(ProceedingJoinPoint joinPoint) {try {Object[] args = joinPoint.getArgs();if (args != null && args.length > 0) {Map<String, Object> map = new HashMap<>();for (Object arg : args) {if (arg instanceof HttpServletRequest) {HttpServletRequest request = (HttpServletRequest) arg;map.put("parameterMap", request.getParameterMap());} else if (arg instanceof HttpServletResponse) {continue;} else {map.put("body", arg);}}return JSONObject.toJSONString(map);}} catch (Exception e) {log.error("获取入参异常:" + e.getMessage(),e);}return "";}}
4、启动类注解扫描 @EnableAspectJAutoProxy
@EnableAspectJAutoProxy
@ComponentScan(basePackages={"com.xpf.*"})
@SpringBootApplication
public class MySpringTestApplication {public static void main(String[] args) {SpringApplication.run(MySpringTestApplication.class, args);}}
5、模拟监控controller
HelloController
@RestController
@ApiLog
public class HelloController {@GetMapping("/hello")public Map<String,Object> getHello(@RequestBody Map hashmap){HashMap map = new HashMap();map.put("key","hello!");map.put("aaa", null);return map;}
}