@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface TimeConsumeLog {
boolean skipResponseLog() default false;
}
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.PARAMETER})
public @interface LogParam {
}
@Slf4j
@Aspect
@Component
public class TimeConsumeLogAspect {
/**
* 日志前缀
*/
static String LOG_PREFIX = "[%s]-[%s]";
/**
* 日志后缀
*/
static String LOG_SUFFIX = "%s-参数[%s]";
/**
* 异常后缀
*/
static String EXCEPTION_SUFFIX = "{}-耗时[{}]毫秒-异常:{}";
/**
* 耗时后缀
*/
static String TIME_SUFFIX = "{}-耗时[{}]毫秒-请求结果:[{}]";
/**
* 记录方法执行时间
*
* @param proceedingJoinPoint
* @param logExecuteTime
* @return
*/
@Around("@annotation(logExecuteTime)")
public Object logExecuteTime(ProceedingJoinPoint proceedingJoinPoint, TimeConsumeLog logExecuteTime) throws Throwable {
long startTime = System.currentTimeMillis();
Object[] args = proceedingJoinPoint.getArgs();
Object[] logArgList = new Object[args.length];
Class<?> targetClass = proceedingJoinPoint.getTarget().getClass();
MethodSignature methodSignature = (MethodSignature) proceedingJoinPoint.getSignature();
Method method = targetClass.getMethod(methodSignature.getName(), methodSignature.getParameterTypes());
Annotation[][] parameterAnnotations = method.getParameterAnnotations();
// 用了LogParam注解的实参都打印出来
for (int argIndex = 0; argIndex < args.length; argIndex++) {
for (Annotation paramAnnotation : parameterAnnotations[argIndex]) {
if (!(paramAnnotation instanceof LogParam)) {
continue;
}
logArgList[argIndex] = args[argIndex];
}
}
String className = targetClass.getName();
String message = String.format(LOG_PREFIX, className, method.getName());
StringBuilder argLogStringBD = new StringBuilder();
for (Object ag : logArgList) {
if (null != ag) {
argLogStringBD.append(String.format("%s:%s ", ag.getClass().getSimpleName(), JsonUtil.toJSON(ag)));
}
}
if (StringUtil.isNotEmpty(argLogStringBD.toString())) {
message = String.format(LOG_SUFFIX, message, argLogStringBD.toString());
}
Object result = null;
Throwable tb = null;
try {
result = proceedingJoinPoint.proceed();
} catch (Throwable throwable) {
tb = throwable;
throw throwable;
} finally {
long consumeTs = System.currentTimeMillis() - startTime;
if (null != tb) {
// 异常时也把参数打出来
log.error(EXCEPTION_SUFFIX, message, consumeTs, ExceptionUtils.getFullStackTrace(tb));
} else {
if (logExecuteTime.skipResponseLog()) {
log.info(TIME_SUFFIX, message, consumeTs, "方法返回结果的日志已跳过");
} else {
String jsonString = null != result ? JsonUtil.toJSON(result) : "null";
log.info(TIME_SUFFIX, message, consumeTs, jsonString);
}
}
}
return result;
}
}