@Documented
@Retention(RUNTIME)
@Target({ElementType.METHOD,ElementType.TYPE})
public @interface ParamResultLog {
}
@Component
@Aspect
public class ParamResultLogAspect {
private Logger logger = LoggerFactory.getLogger(getClass());
@Pointcut("@annotation(com.*类全路径*.ParamResultLog) || @within(com.*类全路径*.ParamResultLog)")
private void cut() { }
private Map<String,Long> timeMap = new HashMap<>();
@Before("cut()")
public void doBefore(JoinPoint joinPoint) {
//类名
String className = joinPoint.getSignature().getDeclaringTypeName();
//方法名称
String methodName = joinPoint.getSignature().getName();
//方法开始时间
timeMap.put(Thread.currentThread().getId()+className+":"+methodName+"start",System.currentTimeMillis());
//防止参数转换报错
try{
//方法参数
Object[] param = new Object[joinPoint.getArgs().length];
for (int i = 0;i<joinPoint.getArgs().length;i++){
if(joinPoint.getArgs()[i] != null&&!(joinPoint.getArgs()[i] instanceof Proxy)){
param[i] = joinPoint.getArgs()[i];
}else{
param[i] = null;
}
}
String argsJsonStr = JSON.toJSONString(param);
logger.info("【{}:{}】开始执行,参数:{}",className,methodName,argsJsonStr);
}catch (Exception e){
logger.warn("Before日志参数转换异常,不影响业务逻辑!信息:{}",e.getMessage());
}
}
@AfterReturning(returning = "ret", pointcut = "cut()")
public void doAfterReturning(JoinPoint joinPoint, Object ret) {
//类名
String className = joinPoint.getSignature().getDeclaringTypeName();
//方法名称
String methodName = joinPoint.getSignature().getName();
//防止参数转换报错
try{
//方法开始时间
timeMap.put(Thread.currentThread().getId()+className+":"+methodName+"end",System.currentTimeMillis());
Long cost = timeMap.get(Thread.currentThread().getId()+className+":"+methodName+"end")-timeMap.get(Thread.currentThread().getId()+className+":"+methodName+"start");
String retStr = JSON.toJSONString(ret);
logger.info("【{}:{}】执行完毕,返回值:{};花费时间{}ms",className,methodName,retStr,cost);
}catch (Exception e){
logger.warn("AfterReturning日志参数转换异常,不影响业务逻辑!信息:{}",e.getMessage());
}finally {
timeMap.remove(Thread.currentThread().getId()+className+":"+methodName+"start");
timeMap.remove(Thread.currentThread().getId()+className+":"+methodName+"end");
}
}
@AfterThrowing(pointcut = "cut()", throwing = "e")
public void doAfterThrowing(JoinPoint joinPoint, Throwable e) {
//类名
String className = joinPoint.getSignature().getDeclaringTypeName();
//方法名称
String methodName = joinPoint.getSignature().getName();
try{
//方法开始时间
timeMap.put(Thread.currentThread().getId()+className+":"+methodName+"end",System.currentTimeMillis());
Long cost = timeMap.get(Thread.currentThread().getId()+className+":"+methodName+"end")-timeMap.get(Thread.currentThread().getId()+className+":"+methodName+"start");
logger.warn("【{}:{}】执行完毕,发生异常:{};花费时间{}ms",className,methodName,e.getMessage(),cost);
}catch (Exception e1){
logger.warn("AfterThrowing日志参数转换异常,不影响业务逻辑!信息:{}",e.getMessage());
}finally {
timeMap.remove(Thread.currentThread().getId()+className+":"+methodName+"start");
timeMap.remove(Thread.currentThread().getId()+className+":"+methodName+"end");
}
}
}
@ParamResultLog 可作用于类或者某个方法,实现方法的出入参打印,方法执行时间捕获。