@Aspect
@Component
@Lazy(false)
public class ApiCallAdvice {
private static final String FORMAT_PATTERN_DAY = "yyyy-MM-dd";
private static final String FORMAT_PATTERN_HOUR = "yyyy-MM-dd HH";
private static final String FORMAT_PATTERN_MILLS = "yyyy-MM-dd HH:mm:ss:SSS";
private static final Logger logger = Logger.getLogger(ApiCallAdvice.class);
/**
* 如果有返回结果,代表一次调用,则对应接口的调用次数加一,统计维度为天
* 统计每小时调用次数
* (Redis使用Hash结构)
* key = URI
* key = date (精确到天)
* value = 调用次数
*/
@AfterReturning("execution(* com.demo.controller.*.*(..))")
protected void afterReturning() {
// 接收到请求,记录请求内容
ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
//获取请求的request
HttpServletRequest request = attributes.getRequest();
String uri = request.getRequestURI();
String date_day = dateFormat(FORMAT_PATTERN_DAY);
String date_hour = dateFormat(FORMAT_PATTERN_HOUR);
//这里自己封装的redis库,意思是插入数据并添加1
Redis.getInstance().hIncrement(uri, date_day);
Redis.getInstance().hIncrement(uri, date_hour);
}
/**
* 如果调用抛出异常,则缓存异常信息(Redis使用Hash结构)
* key = URI + “_exception”
* key = time (精确到毫秒的时间)
* value = exception 异常信息
*
* @param ex 异常信息
*/
@AfterThrowing(value = "execution(* com.demo.controller.*.*(..))", throwing = "ex")
protected void afterThrowing(Exception ex) {
ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
HttpServletRequest request = attributes.getRequest();
String uri = request.getRequestURI() + "_exception";
String time = dateFormat(FORMAT_PATTERN_MILLS);
String exception = ex.getMessage();
Redis.getInstance().hset(uri, time, exception);
}
@Around("execution(* com.demo.controller.*.*(..))")
protected Object around(ProceedingJoinPoint joinPoint) throws Throwable {
ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
HttpServletRequest request = attributes.getRequest();
String requestURI = request.getRequestURI();
Signature signature = joinPoint.getSignature();
StopWatch stopWatch = new StopWatch();
stopWatch.start();
try {
Object result = joinPoint.proceed();
stopWatch.stop();
logger.info("接口:" +requestURI + "; 方法名:"+signature.getName()+ "; cost: " + stopWatch.getTotalTimeSeconds() + "秒");
return result;
} catch (Exception e) {
logger.error(e);
throw e;
}
}
private String dateFormat(String pattern) {
SimpleDateFormat dateFormat = new SimpleDateFormat(pattern);
return dateFormat.format(new Date());
}
}
以上代码是为了测试使用,如果实际生产环境,有其他方法监控调用等信息。感兴趣了解全链路监控