package com.qxueyou.scc.base.handler; import java.io.Serializable; import java.util.Collection; import java.util.HashMap; import java.util.List; import java.util.Map; import javax.servlet.http.HttpServletRequest; import org.apache.commons.lang3.StringUtils; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.aspectj.lang.JoinPoint; 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.springframework.beans.factory.annotation.Autowired; import org.springframework.core.annotation.AnnotationUtils; import org.springframework.core.annotation.Order; import org.springframework.expression.EvaluationContext; import org.springframework.expression.ExpressionParser; import org.springframework.expression.ParserContext; import org.springframework.expression.spel.standard.SpelExpressionParser; import org.springframework.expression.spel.support.StandardEvaluationContext; import org.springframework.stereotype.Component; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.context.request.RequestContextHolder; import org.springframework.web.context.request.ServletRequestAttributes; import com.alibaba.fastjson.JSON; import com.qxueyou.scc.base.util.ClientUtils; import com.qxueyou.scc.base.util.RequestClientUtils; import com.qxueyou.scc.base.util.TraceUtils; import com.qxueyou.scc.sys.model.SysLog; import com.qxueyou.scc.sys.service.ISysLogService; @Order(90) @Aspect @Component public class QLogMonitor { private static final Logger logger = LogManager.getLogger("QLogMonitor"); @Autowired ISysLogService logService; @Pointcut("execution(public * com.iqtogether.qxueyou..action.*Controller.*(..))") public void pointCutMethod() { } @Before("pointCutMethod()") public void doAfter(JoinPoint joinPoint) throws Throwable { ServletRequestAttributes servletWebRstRequest = null; HttpServletRequest request = null; MethodSignature methodSignature = null; String userAgent = null; String ip = null; String strContent = null; String strDesp = null; String strModule = ""; QLog.LogType qLogType = QLog.LogType.SYS; short sLogType = -1; QLog qLog = null; try { methodSignature = (MethodSignature) joinPoint.getSignature(); if (RequestContextHolder.getRequestAttributes() != null) { servletWebRstRequest = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes(); request = servletWebRstRequest.getRequest(); userAgent = request.getHeader("user-agent"); if(StringUtils.isNotEmpty(userAgent) && userAgent.length()>255){ userAgent = userAgent.substring(0,255); } ip = RequestClientUtils.getRemoteIP(request); } qLog = AnnotationUtils.findAnnotation(methodSignature.getMethod(), QLog.class); if (qLog != null) { strContent = parserSpel(qLog.content(), joinPoint); strDesp = parserSpel(qLog.desp(), joinPoint); strModule = parserSpel(qLog.module(), joinPoint); qLogType = qLog.type(); } // 默认为参数相关信息 if (StringUtils.isEmpty(strContent)) { strContent = createDefaultContentInfo(joinPoint, methodSignature); } // 默认为请求的URI信息 if(StringUtils.isEmpty(strDesp) && request!=null){ strDesp =request.getRequestURI(); } // 默认为:控制器模块注解value值+方法名 if (StringUtils.isEmpty(strModule)) { strModule = createDefaultModuleInfo(joinPoint); } sLogType = (short) (QLog.LogType.SYS.equals(qLogType) ? 0 : 1); this.saveLog(strContent, strDesp, strModule.toUpperCase(), sLogType, ip,userAgent); } catch (Exception e) { logger.error("记录action操作日志发生异常!,errMsg:" + e.getMessage(), e); } } private String createDefaultModuleInfo(JoinPoint joinPoint) { String strModule = ""; RequestMapping classReqMap = AnnotationUtils.findAnnotation(joinPoint.getTarget().getClass(), RequestMapping.class); if (classReqMap != null && classReqMap.value() != null && classReqMap.value().length > 0 && StringUtils.isNotEmpty(classReqMap.value()[0])) { if (classReqMap.value()[0].startsWith("/")) { strModule = classReqMap.value()[0].substring(1); } if (StringUtils.isNotEmpty(strModule)) { strModule = strModule.concat("_").concat(joinPoint.getSignature().getName()); } else { strModule = "ROOT".concat("_").concat(joinPoint.getSignature().getName()); } strModule = strModule.replaceAll("/", "_"); } if(StringUtils.isNotEmpty(strModule) && strModule.length()>64){ strModule = strModule.substring(0, 64); } return strModule; } private String createDefaultContentInfo(JoinPoint joinPoint, MethodSignature methodSignature) { String strDesp=""; if (joinPoint.getArgs() != null && joinPoint.getArgs().length > 0) { Map parmaMap = new HashMap(joinPoint.getArgs().length); for (int i = 0; i < joinPoint.getArgs().length; i++) { if (joinPoint.getArgs()[i] == null) { parmaMap.put(methodSignature.getParameterNames()[i], ""); } else { if (this.checkParam(joinPoint.getArgs()[i].getClass())) { parmaMap.put(methodSignature.getParameterNames()[i], joinPoint.getArgs()[i]); } } } if (!parmaMap.isEmpty()) { strDesp = JSON.toJSONString(parmaMap); if (strDesp.length() > 250) { strDesp = strDesp.substring(0, 250).concat(".."); } } } return strDesp; } private void saveLog(String content, String desp, String module, short type, String ip,String userAgent) { SysLog lg = new SysLog(); TraceUtils.setCreateActiveTrace(lg); lg.setUserId(ClientUtils.getUserId()); lg.setUserName(ClientUtils.getUserName()); lg.setDeleteFlag(Boolean.FALSE); lg.setContent(content); lg.setDesp(desp); lg.setModule(module); lg.setType(type); lg.setIp(ip); lg.setUserAgent(userAgent); logService.insertLog(lg); } private boolean checkParam(Class paramClz) { if (paramClz.isPrimitive()) { return true; } else if (Byte.class.isAssignableFrom(paramClz)) { return true; } else if (Character.class.isAssignableFrom(paramClz)) { return true; } else if (Boolean.class.isAssignableFrom(paramClz)) { return true; } else if (Short.class.isAssignableFrom(paramClz)) { return true; } else if (Integer.class.isAssignableFrom(paramClz)) { return true; } else if (Long.class.isAssignableFrom(paramClz)) { return true; } else if (Float.class.isAssignableFrom(paramClz)) { return true; } else if (Double.class.isAssignableFrom(paramClz)) { return true; } else if (String.class.isAssignableFrom(paramClz)) { return true; } else if (Map.class.isAssignableFrom(paramClz)) { return true; } else if (List.class.isAssignableFrom(paramClz)) { return true; } else if (Collection.class.isAssignableFrom(paramClz)) { return true; } else if (paramClz.isArray()) { return true; } else if (Serializable.class.isAssignableFrom(paramClz)) { return true; } return false; } private String parserSpel(String strTemplate, JoinPoint joinPoint) { MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature(); ExpressionParser parser = new SpelExpressionParser(); EvaluationContext ctx = new StandardEvaluationContext(); // 设置变量 if (joinPoint.getArgs() != null && joinPoint.getArgs().length > 0) { for (int i = 0; i < joinPoint.getArgs().length; i++) { if (joinPoint.getArgs()[i] != null && this.checkParam(joinPoint.getArgs()[i].getClass())) { ctx.setVariable(methodSignature.getParameterNames()[i], joinPoint.getArgs()[i]); } } } String parsedString = parser.parseExpression(strTemplate, new ParserContext() { @Override public boolean isTemplate() { return true; } @Override public String getExpressionSuffix() { return "}"; } @Override public String getExpressionPrefix() { return "{"; } }).getValue(ctx, String.class); return parsedString; } }