package com.iplatform.base.support; import com.iplatform.base.AsyncManager; import com.iplatform.base.SecuritySpi; import com.iplatform.base.service.LogServiceImpl; import com.iplatform.model.po.S_oper_log; import com.iplatform.model.po.S_user_core; import com.walker.infrastructure.utils.JsonUtils; import com.walker.infrastructure.utils.StringUtils; import com.walker.web.Constants; import com.walker.web.ResponseCode; import com.walker.web.log.BusinessType; import com.walker.web.log.Log; import com.walker.web.util.IpUtils; import com.walker.web.util.ServletUtils; import org.aspectj.lang.JoinPoint; import org.aspectj.lang.annotation.AfterReturning; import org.aspectj.lang.annotation.AfterThrowing; import org.aspectj.lang.annotation.Aspect; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.validation.BindingResult; import org.springframework.web.multipart.MultipartFile; import org.springframework.web.servlet.HandlerMapping; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.util.Collection; import java.util.Map; import java.util.TimerTask; /** * 操作日志切面对象定义。
** 1)业务在自己的调用方法上添加注解即可自动完成操作日志记录 * 2)注解示例: * @Log(title = "用户管理", businessType = BusinessType.Insert, isSaveRequestData = true, isSaveResponseData = false) ** @date 2023-01-06 */ @Aspect public class LogAspect { protected final transient Logger logger = LoggerFactory.getLogger(this.getClass()); private static final int MAX_DATA_SIZE = 2000; private static final int MAX_ERROR_SIZE = com.iplatform.base.Constants.LOG_ERROR_MAX_SIZE; private SecuritySpi securitySpi; private LogServiceImpl logService; private boolean enableLog = true; /** * 配置是否打开或关闭日志写入。 * @param enableLog */ public void setEnableLog(boolean enableLog) { this.enableLog = enableLog; } public void setLogService(LogServiceImpl logService) { this.logService = logService; } public void setSecuritySpi(SecuritySpi securitySpi) { this.securitySpi = securitySpi; } /** * 处理完请求后执行 * @param joinPoint 切点 */ @AfterReturning(pointcut = "@annotation(logAnnotation)", returning = "jsonResult") public void doAfterReturning(JoinPoint joinPoint, Log logAnnotation, Object jsonResult) { if(this.enableLog){ handleLog(joinPoint, logAnnotation, null, jsonResult); } } /** * 拦截异常操作 * @param joinPoint 切点 * @param e 异常 */ @AfterThrowing(value = "@annotation(logAnnotation)", throwing = "e") public void doAfterThrowing(JoinPoint joinPoint, Log logAnnotation, Exception e) { if(this.enableLog){ handleLog(joinPoint, logAnnotation, e, null); } } private void handleLog(final JoinPoint joinPoint, Log logAnnotation, final Exception e, Object jsonResult){ try{ S_oper_log s_oper_log = new S_oper_log(); S_user_core user_core = this.securitySpi.getCurrentUser(); if(user_core != null){ s_oper_log.setOper_name(user_core.getUser_name()); } if(e == null){ s_oper_log.setStatus(ResponseCode.SUCCESS.getCode()); } else { s_oper_log.setStatus(ResponseCode.ERROR.getCode()); s_oper_log.setError_msg(StringUtils.substring(e.getMessage(), 0, MAX_ERROR_SIZE)); } String requestMethod = ServletUtils.getRequest().getMethod(); String ip = IpUtils.getIpAddr(ServletUtils.getRequest()); s_oper_log.setOper_ip(ip); s_oper_log.setOper_url(ServletUtils.getRequest().getRequestURI()); // 设置方法名称 String className = joinPoint.getTarget().getClass().getName(); String methodName = joinPoint.getSignature().getName(); s_oper_log.setMethod(className + "." + methodName); s_oper_log.setRequest_method(requestMethod); s_oper_log.setOper_location(StringUtils.EMPTY_STRING); s_oper_log.setTitle(logAnnotation.title()); s_oper_log.setOperate_user(logAnnotation.operatorType().getIndex()); // BusinessType businessType = logAnnotation.businessType(); s_oper_log.setBusiness_type(businessType.getIndex()); if(logAnnotation.isSaveRequestData() && businessType.isSaveRequest()){ // 只有开发设置注解以及业务类型都允许保存时才真正保存数据 if(requestMethod.equals(Constants.HTTP_METHOD_POST) || requestMethod.equals(Constants.HTTP_METHOD_PUT)){ String params = argsArrayToString(joinPoint.getArgs()); if(StringUtils.isNotEmpty(params)){ s_oper_log.setOper_param(params); } } else { Map, ?> paramsMap = (Map, ?>) ServletUtils.getRequest().getAttribute(HandlerMapping.URI_TEMPLATE_VARIABLES_ATTRIBUTE); if(paramsMap != null){ s_oper_log.setOper_param(StringUtils.substring(paramsMap.toString(), 0, MAX_DATA_SIZE)); } } } if(logAnnotation.isSaveResponseData() && businessType.isSaveResponse()){ // 只有开发设置注解以及业务类型都允许保存时才真正保存数据 if(jsonResult != null){ String res = JsonUtils.objectToJsonString(jsonResult); if(StringUtils.isNotEmpty(res)){ s_oper_log.setJson_result(StringUtils.substring(res, 0, MAX_DATA_SIZE)); } } } AsyncManager.me().execute(this.acquireOperateLogTask(s_oper_log)); }catch (Exception ex){ if(logger.isDebugEnabled()){ logger.error(ERROR_LOG, ex); } else { logger.error(ERROR_LOG + ex.getMessage()); } } } private String argsArrayToString(Object[] paramsArray){ try { StringBuilder sb = new StringBuilder(); if (paramsArray != null && paramsArray.length > 0){ for (Object o : paramsArray){ if(o == null){ continue; } if(!this.isFilterObject(o)){ sb.append(JsonUtils.objectToJsonString(o)).append(StringUtils.SEPARATOR_SEMI_COLON); } } } return sb.toString(); } catch (Exception e){ return StringUtils.EMPTY_STRING; } } /** * 判断是否需要过滤的对象。 * * @param o 对象信息。 * @return 如果是需要过滤的对象,则返回true;否则返回false。 */ private boolean isFilterObject(final Object o) { Class> clazz = o.getClass(); if (clazz.isArray()) { return clazz.getComponentType().isAssignableFrom(MultipartFile.class); } else if (Collection.class.isAssignableFrom(clazz)) { Collection collection = (Collection) o; for (Object value : collection) { return value instanceof MultipartFile; } } else if (Map.class.isAssignableFrom(clazz)) { Map map = (Map) o; for (Object value : map.entrySet()) { Map.Entry entry = (Map.Entry) value; return entry.getValue() instanceof MultipartFile; } } return o instanceof MultipartFile || o instanceof HttpServletRequest || o instanceof HttpServletResponse || o instanceof BindingResult; } private TimerTask acquireOperateLogTask(S_oper_log s_oper_log){ return new TimerTask() { @Override public void run() { // s_oper_log.setOper_time(DateUtils.getDateTimeNumber(System.currentTimeMillis())); // s_oper_log.setOper_id(NumberGenerator.getLongSequenceNumber()); logService.execInsertOperateLog(s_oper_log); } }; } private static final String ERROR_LOG = "日志切面记录异常:"; }