每次搭建新项目都会用到拦截器,这次把以前用过的一个拦截器进行改造了一下,放blog做个记录
package com.xxx.aop;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
@Aspect
@Order
@Component
public class LogAspect {
private static final Logger logger = LoggerFactory.getLogger(LogAspect.class);
@Around(value = "execution(* com.xxx.service..*.*(..))")
public Object printLog(ProceedingJoinPoint jp) {
CallerInfo info = null;
Object ret = null;
long startTime = System.currentTimeMillis();
try {
String key = getMethodName(jp);
info = Profiler.registerInfo(key, false, true);
ret = jp.proceed();
logCompleted(jp, ret, startTime);
Profiler.registerInfoEnd(info);
return ret;
} catch (Throwable throwable) {
String exInfo = logException(jp, startTime, throwable);
Profiler.functionError(info);
return ResultUtils.wrapFailure(500, exInfo);
}
}
private void logCompleted(ProceedingJoinPoint jp, Object ret, long startTime) {
StringBuilder sb = new StringBuilder();
logBasic(sb, jp, startTime);
logSuccessResult(sb, ret);
logger.info(sb.toString());
}
private String logException(ProceedingJoinPoint jp, long startTime, Throwable throwable) {
StringBuilder sb = new StringBuilder();
logBasic(sb, jp, startTime);
logExceptionResult(sb, throwable);
String message = sb.toString();
logger.error(message);
return message;
}
private void logBasic(StringBuilder sb, ProceedingJoinPoint jp, long startTime) {
String params = "";
try {
if (jp.getArgs() != null) {
params = JSON.toJSONString(jp.getArgs());
}
} catch (Exception ex) {
logger.warn("aop序列化参数失败", ex);
}
buildPrefix(sb, jp, startTime);
sb.append("#parameter:");
sb.append(params);
sb.append("#result:");
}
private void logExceptionResult(StringBuilder sb, Throwable throwable) {
String result = throwable.toString();
sb.append(result);
sb.append("###stack:");
sb.append(ExceptionUtil.getStackTrace(throwable));
}
private void logSuccessResult(StringBuilder sb, Object ret) {
String result = "";
try {
if (ret != null) {
result = JSON.toJSONString(ret);
}
} catch (Exception ex) {
logger.warn("aop序列化结果失", ex);
}
sb.append(result);
}
private void buildPrefix(StringBuilder sb, ProceedingJoinPoint jp, long startTime) {
long cost = System.currentTimeMillis() - startTime;
String clazz = jp.getTarget().getClass().getSimpleName();
String method = jp.getSignature().getName();
sb.append("class:");
sb.append(clazz);
sb.append("#method:");
sb.append(method);
sb.append("#cost:");
sb.append(cost);
}
private String getMethodName(ProceedingJoinPoint jp) {
StringBuilder sb = new StringBuilder();
String clazz = jp.getTarget().getClass().getName();
String method = jp.getSignature().getName();
sb.append(clazz);
sb.append(".");
sb.append(method);
return sb.toString();
}
}
插入一个异常详细信息收集器
public static String getStackTrace(Throwable throwable) {
StringWriter sw = new StringWriter();
PrintWriter pw = new PrintWriter(sw);
try {
throwable.printStackTrace(pw);
return sw.toString();
} finally {
pw.close();
try {
sw.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
记录结果如下:
2020-04-02 16:14:13.493 | c.a.b.c.LogAspect | INFO | class:MyService#method:logTest#cost:386#parameter:[{"myId":110,"myName":"ikong"}]#result:{"code":0,"data":[],"message":"","success":true}