package com.apt.aop;
import java.util.Map;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import com.alibaba.fastjson.JSONObject;
import com.apt.dao.log.LogInfoRepository;
import com.apt.dao.log.LogInfoRepositoryImpl;
import com.apt.model.log.LogInfo;
import com.apt.util.ChkUtil;
import com.apt.util.date.DateUtil;
@Component
@Aspect
public class ExceptionLogHandler {
private final static Logger logger = LoggerFactory.getLogger(ExceptionLogHandler.class);
private final static String PROJECT_NAME = "cf_api";
@Resource
private LogInfoRepository logInfoRepository;
@Resource
private LogInfoRepositoryImpl loginfoImpl;
@Pointcut("execution(* com.apt.web..*.*(..))")
public void exceptionLog() {
}
@Around("exceptionLog()")
public Object around(JoinPoint joinPoint) {
LogInfo logInfo = new LogInfo();
logInfo.setProjectName(PROJECT_NAME);
logInfo.setCreateTime(DateUtil.getCurrentTime());
//Map<String,Object> map = new HashMap<String,Object>();
JSONObject json = new JSONObject();
Object reuslt = null;
try {
String targetName = joinPoint.getTarget().getClass().getName();
Signature signature = joinPoint.getSignature();
MethodSignature methodSignature = (MethodSignature) signature;
String methodName = methodSignature.getName();
String[] params = methodSignature.getParameterNames();
Object[] arguments = joinPoint.getArgs();
for(int i=0; i<params.length; i++) {
if(arguments[i] instanceof HttpServletRequest) {
HttpServletRequest request = (HttpServletRequest)arguments[i];
Map<String,String[]> map = request.getParameterMap();
if(map != null) {
for (String key : map.keySet()) {
String[] value = map.get(key);
json.put(key, value[0]);
}
}
}
if(arguments[i] instanceof HttpServletResponse || arguments[i] instanceof HttpServletRequest) continue;
json.put(params[i], arguments[i]);
}
logInfo.setLogClass(targetName);
logInfo.setLogMethod(methodName);
RequestAttributes ra = RequestContextHolder.getRequestAttributes();
String ip = "";
if(ra != null) {
ServletRequestAttributes sra = (ServletRequestAttributes) ra;
HttpServletRequest request = sra.getRequest();
String url = request.getRequestURL().toString();
/*String method = request.getMethod();
String uri = request.getRequestURI();
String queryString = request.getQueryString();*/
ip = request.getRemoteAddr();
logInfo.setRequestIp(ip);
logInfo.setRequestUrl(url);
}
/*ClassPool pool = ClassPool.getDefault();
ClassClassPath classPath = new ClassClassPath(joinPoint.getTarget().getClass());
pool.insertClassPath(classPath);
CtClass cc = pool.get(targetName);
CtMethod cm = cc.getDeclaredMethod(methodName);
MethodInfo methodInfo = cm.getMethodInfo();
CodeAttribute codeAttribute = methodInfo.getCodeAttribute();
LocalVariableAttribute attr = (LocalVariableAttribute) codeAttribute.getAttribute(LocalVariableAttribute.tag);
if (attr == null) {
// exception
}
String[] paramNames = new String[cm.getParameterTypes().length];
int pos = Modifier.isStatic(cm.getModifiers()) ? 0 : 1;
for (int i = 0; i < paramNames.length; i++) {
paramNames[i] = attr.variableName(i + pos);
}
for (int i = 0; i < paramNames.length; i++) {
if(arguments[i] instanceof HttpServletRequest || arguments[i] instanceof HttpServletResponse) continue;
map.put(paramNames[i], arguments[i]);
} */
logInfo.setRequestParam(json.toString());
} catch(Exception e) {
logger.info(e.getMessage(),e);
logInfo.setErrorMsg(e.getMessage());
e.fillInStackTrace();
}
try{
ProceedingJoinPoint point = (ProceedingJoinPoint) joinPoint;
reuslt = point.proceed();
if(!ChkUtil.isEmpty(reuslt)) {
logInfo.setResponseResult(reuslt.toString());
}
} catch (Throwable e) {
String msg = errorClassInfo(e);
logInfo.setErrorMsg(msg+e.fillInStackTrace().getMessage());
}
try{
logInfo.setEndTime(DateUtil.getCurrentTime());
logInfoRepository.save(logInfo);
}catch (Exception e) {
logger.info(e.getMessage(),e);
}
return reuslt;
}
//打印抛出异常地方的信息
private String errorClassInfo(Throwable ex) {
/*
* ex.getStackTrace()返回堆栈跟踪元素的数组,每个元素表示一个堆栈帧。数组的第零个元素(假定数据的长度为非零)表示堆栈顶部,
* 它是序列中最后的方法调用。
* 通常,这是创建和抛出该 throwable 的地方。数组的最后元素(假定数据的长度为非零)表示堆栈底部,它是序列中第一个方法调用
*/
StackTraceElement[] stackTraceElementArr= ex.getStackTrace();
StackTraceElement stackTraceElement = stackTraceElementArr[0];
String msg = "Erro File:" + stackTraceElement.getFileName();
msg += "Erro Method:" + stackTraceElement.getMethodName();
msg += "Erro Line:" + stackTraceElement.getLineNumber();
return msg;
}
}