|
@@ -1,12 +1,24 @@
|
|
|
package com.xt.js.gkaq.common.log.aspect;
|
|
|
|
|
|
+import java.lang.reflect.Field;
|
|
|
import java.lang.reflect.Method;
|
|
|
+import java.util.Date;
|
|
|
|
|
|
+import javax.servlet.http.HttpServletRequest;
|
|
|
+
|
|
|
+import org.apache.ibatis.javassist.ClassClassPath;
|
|
|
+import org.apache.ibatis.javassist.ClassPool;
|
|
|
+import org.apache.ibatis.javassist.CtClass;
|
|
|
+import org.apache.ibatis.javassist.CtMethod;
|
|
|
+import org.apache.ibatis.javassist.Modifier;
|
|
|
+import org.apache.ibatis.javassist.bytecode.CodeAttribute;
|
|
|
+import org.apache.ibatis.javassist.bytecode.LocalVariableAttribute;
|
|
|
+import org.apache.ibatis.javassist.bytecode.MethodInfo;
|
|
|
import org.aspectj.lang.JoinPoint;
|
|
|
import org.aspectj.lang.Signature;
|
|
|
+import org.aspectj.lang.annotation.After;
|
|
|
import org.aspectj.lang.annotation.AfterThrowing;
|
|
|
import org.aspectj.lang.annotation.Aspect;
|
|
|
-import org.aspectj.lang.annotation.Before;
|
|
|
import org.aspectj.lang.annotation.Pointcut;
|
|
|
import org.aspectj.lang.reflect.MethodSignature;
|
|
|
import org.slf4j.Logger;
|
|
@@ -17,6 +29,8 @@ import org.springframework.stereotype.Component;
|
|
|
import com.xt.js.gkaq.common.Constants;
|
|
|
import com.xt.js.gkaq.common.ex.BusinessException;
|
|
|
import com.xt.js.gkaq.common.log.annotation.SysLog;
|
|
|
+import com.xt.js.gkaq.common.util.DateUtil;
|
|
|
+import com.xt.js.gkaq.common.util.IpUtil;
|
|
|
import com.xt.js.gkaq.frame.model.SysLogModel;
|
|
|
import com.xt.js.gkaq.frame.service.SysLogService;
|
|
|
|
|
@@ -31,30 +45,35 @@ public class SysLogAspect {
|
|
|
// 日志对象
|
|
|
private static final Logger logger = LoggerFactory.getLogger(SysLogAspect.class);
|
|
|
|
|
|
+ private static String[] paramTypes = { "java.lang.Integer", "java.lang.Double", "java.lang.Float",
|
|
|
+ "java.lang.Long", "java.lang.Short", "java.lang.Byte", "java.lang.Boolean", "java.lang.Char",
|
|
|
+ "java.lang.String", "int", "double", "long", "short", "byte", "boolean", "char", "float" };
|
|
|
+
|
|
|
// 日志切入点
|
|
|
@Pointcut("@annotation(com.xt.js.gkaq.common.log.annotation.SysLog)")
|
|
|
public void sysLogPointcut() {
|
|
|
}
|
|
|
|
|
|
+ // /**
|
|
|
+ // * 前置通知
|
|
|
+ // *
|
|
|
+ // * @param joinPoint
|
|
|
+ // */
|
|
|
+ // @Before("sysLogPointcut()")
|
|
|
+ // public void doBefore(JoinPoint joinPoint) {
|
|
|
+ // genSysLog(joinPoint, null);
|
|
|
+ // }
|
|
|
+
|
|
|
/**
|
|
|
- * 前置通知
|
|
|
+ * 后置通知
|
|
|
*
|
|
|
* @param joinPoint
|
|
|
*/
|
|
|
- @Before("sysLogPointcut()")
|
|
|
- public void doBefore(JoinPoint joinPoint) {
|
|
|
+ @After("sysLogPointcut()")
|
|
|
+ public void doAfter(JoinPoint joinPoint) {
|
|
|
genSysLog(joinPoint, null);
|
|
|
}
|
|
|
|
|
|
- // /**
|
|
|
- // * 后置通知
|
|
|
- // * @param joinPoint
|
|
|
- // */
|
|
|
- // @AfterReturning(pointcut = "sysLogPointcut()")
|
|
|
- // public void doAfter(JoinPoint joinPoint) {
|
|
|
- // genSysLog(joinPoint, null);
|
|
|
- // }
|
|
|
-
|
|
|
/**
|
|
|
* 异常通知
|
|
|
*
|
|
@@ -79,37 +98,47 @@ public class SysLogAspect {
|
|
|
// 获取目标类名
|
|
|
String targetName = joinPoint.getTarget().getClass().getName();
|
|
|
// 类路径
|
|
|
- String classPath = targetName + "." + methodName + "()";
|
|
|
+ String logPath = targetName + "." + methodName + "()";
|
|
|
// 获取系统日志注解
|
|
|
SysLog sysLog = getSysLogAnnotation(joinPoint);
|
|
|
if (sysLog == null) {
|
|
|
- logger.error("{}获取系统日志注解为空!", classPath);
|
|
|
+ logger.error("{}获取系统日志注解为空!", logPath);
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
- String description = sysLog.description();
|
|
|
- String type = sysLog.type();
|
|
|
+ String[] paramNames = getMethodParamNames(this.getClass(), targetName, methodName);
|
|
|
+ String logParam = "";
|
|
|
+ if (paramNames != null) {
|
|
|
+ logParam = genMethodParamInfo(paramNames, joinPoint);
|
|
|
+ }
|
|
|
+
|
|
|
+ String logMsg = sysLog.description();
|
|
|
+ String logType = sysLog.type();
|
|
|
if (ex != null) {
|
|
|
if (ex instanceof BusinessException) {
|
|
|
- type = Constants.LOG_TYPE_2;
|
|
|
+ logType = Constants.LOG_TYPE_2;
|
|
|
BusinessException bex = (BusinessException) ex;
|
|
|
- description += "[发生业务异常,异常代码:" + bex.getErrorCode() + ",异常信息:" + bex.getErrorMsg() + "]";
|
|
|
+ logMsg += "[发生业务异常,异常代码:" + bex.getErrorCode() + ",异常信息:" + bex.getErrorMsg() + "]";
|
|
|
} else {
|
|
|
- type = Constants.LOG_TYPE_1;
|
|
|
- description += "[发生异常:" + ex.getMessage() + "]";
|
|
|
+ logType = Constants.LOG_TYPE_1;
|
|
|
+ logMsg += "[发生异常:" + ex.getMessage() + "]";
|
|
|
}
|
|
|
}
|
|
|
- logger.info("生成系统日志[日志类路径:{},日志类型:{},日志描述:{}]", classPath, type, description);
|
|
|
+ HttpServletRequest request = null;
|
|
|
+ String ip = "";//IpUtil.getIpAddr(request);
|
|
|
+ logger.info("生成系统日志[日志类型:{},日志路径:{},日志参数:{},日志描述:{},客户端IP:{}]", logType, logPath, logParam, logMsg);
|
|
|
|
|
|
// 数据库日志
|
|
|
SysLogModel log = new SysLogModel();
|
|
|
- log.setClassPath(classPath);
|
|
|
- log.setType(type);
|
|
|
- log.setMessage(description);
|
|
|
+ log.setLogType(logType);
|
|
|
+ log.setLogPath(logPath);
|
|
|
+ log.setLogParam(logParam);
|
|
|
+ log.setLogMsg(logMsg);
|
|
|
+ log.setClientIp(ip);
|
|
|
// 保存数据库
|
|
|
sysLogService.save(log);
|
|
|
} catch (Exception exp) {
|
|
|
- logger.error("生成系统日志发生异常:", exp);
|
|
|
+ logger.error("生成系统日志发生异常:", exp);
|
|
|
}
|
|
|
}
|
|
|
|
|
@@ -133,4 +162,130 @@ public class SysLogAspect {
|
|
|
return null;
|
|
|
}
|
|
|
|
|
|
+ /**
|
|
|
+ * 获取方法参数的名称
|
|
|
+ *
|
|
|
+ * @param thisClass
|
|
|
+ * @param clazzName
|
|
|
+ * @param methodName
|
|
|
+ * @return
|
|
|
+ */
|
|
|
+ private static String[] getMethodParamNames(Class<?> thisClass, String clazzName, String methodName) {
|
|
|
+
|
|
|
+ String[] paramNames = null;
|
|
|
+ try {
|
|
|
+ ClassPool pool = ClassPool.getDefault();
|
|
|
+
|
|
|
+ ClassClassPath classPath = new ClassClassPath(thisClass);
|
|
|
+ pool.insertClassPath(classPath);
|
|
|
+
|
|
|
+ CtClass cc = pool.get(clazzName);
|
|
|
+ CtMethod cm = cc.getDeclaredMethod(methodName);
|
|
|
+ MethodInfo methodInfo = cm.getMethodInfo();
|
|
|
+ CodeAttribute codeAttribute = methodInfo.getCodeAttribute();
|
|
|
+ LocalVariableAttribute attr = (LocalVariableAttribute) codeAttribute
|
|
|
+ .getAttribute(LocalVariableAttribute.tag);
|
|
|
+ if (attr == null) {
|
|
|
+ throw new Exception(cc.getName() + " : LocalVariableAttribute is null!");
|
|
|
+ }
|
|
|
+ paramNames = new String[cm.getParameterTypes().length];
|
|
|
+ int pos = Modifier.isStatic(cm.getModifiers()) ? 0 : 1;
|
|
|
+ for (int i = 0; i < paramNames.length; i++) {
|
|
|
+ // paramNames即参数名
|
|
|
+ paramNames[i] = attr.variableName(i + pos);
|
|
|
+ }
|
|
|
+ } catch (Exception ex) {
|
|
|
+ logger.error("系统日志生成,获取方法参数的名称时发生异常:", ex);
|
|
|
+ }
|
|
|
+ return paramNames;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 生成方法参数信息
|
|
|
+ *
|
|
|
+ * @param paramNames
|
|
|
+ * @param joinPoint
|
|
|
+ * @return
|
|
|
+ */
|
|
|
+ private static String genMethodParamInfo(String[] paramNames, JoinPoint joinPoint) {
|
|
|
+
|
|
|
+ Object[] args = joinPoint.getArgs();
|
|
|
+ StringBuilder paramInfo = new StringBuilder();
|
|
|
+ boolean clazzFlag = true;
|
|
|
+ try {
|
|
|
+ for (int i = 0; i < args.length; i++) {
|
|
|
+ clazzFlag = true;
|
|
|
+ Object arg = args[i];
|
|
|
+ if (arg == null) {
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ paramInfo.append(paramNames[i]).append(" ");
|
|
|
+ // 获取对象类型
|
|
|
+ String typeName = arg.getClass().getName();
|
|
|
+
|
|
|
+ for (String paramType : paramTypes) {
|
|
|
+ if (paramType.equals(typeName)) {
|
|
|
+ paramInfo.append("= ").append(arg).append("; ");
|
|
|
+ clazzFlag = false;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if (clazzFlag) {
|
|
|
+ paramInfo.append(getClazzParamInfo(arg));
|
|
|
+ }
|
|
|
+ }
|
|
|
+ } catch (Exception ex) {
|
|
|
+ logger.error("系统日志生成,生成方法参数信息时发生异常:", ex);
|
|
|
+ }
|
|
|
+ return paramInfo.toString();
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 获取非基本类型参数信息
|
|
|
+ *
|
|
|
+ * @param obj
|
|
|
+ * @throws IllegalAccessException
|
|
|
+ * @throws IllegalArgumentException
|
|
|
+ */
|
|
|
+ public static String getClazzParamInfo(Object obj) throws IllegalArgumentException, IllegalAccessException {
|
|
|
+
|
|
|
+ if (obj == null) {
|
|
|
+ return "";
|
|
|
+ }
|
|
|
+
|
|
|
+ Field[] fields = obj.getClass().getDeclaredFields();
|
|
|
+ StringBuilder paramInfo = new StringBuilder();
|
|
|
+ boolean clazzFlag = true;
|
|
|
+ String dateType = "java.util.Date";
|
|
|
+
|
|
|
+ paramInfo.append("[");
|
|
|
+ for (Field field : fields) {
|
|
|
+ field.setAccessible(true);
|
|
|
+ if (field.get(obj) == null) {
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ clazzFlag = true;
|
|
|
+ for (String paramType : paramTypes) {
|
|
|
+ if (paramType.equals(field.getType().getName())) {
|
|
|
+ paramInfo.append(field.getName()).append(" = ").append(field.get(obj)).append("; ");
|
|
|
+ clazzFlag = false;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if (clazzFlag) {
|
|
|
+ // 日期类型处理
|
|
|
+ if (dateType.equals(field.getType().getName())) {
|
|
|
+ Date date = (Date) field.get(obj);
|
|
|
+ String dateStr = DateUtil.DateToStr(date, DateUtil.FORMAT_DATE);
|
|
|
+ paramInfo.append(field.getName()).append(" = ").append(dateStr).append("; ");
|
|
|
+ } else {
|
|
|
+ // 递归
|
|
|
+ getClazzParamInfo(field.get(obj));
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ paramInfo.append("]");
|
|
|
+
|
|
|
+ return paramInfo.toString();
|
|
|
+ }
|
|
|
}
|