日志切面
package com.qz.springcloud.school.brain.core.log.annotation; import java.lang.annotation.Documented; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; import com.qz.springcloud.school.brain.core.log.LogDictItemEnum; import com.qz.springcloud.school.brain.core.log.LogType; @Target(ElementType.METHOD) @Retention(RetentionPolicy.RUNTIME) @Documented public @interface LogPoint { /** * 传递到aspect类的参数。 * <p> * 格式:#{spEL}表达式 例如:#{OrgName:#requestVo?.name} 获取请求对象requestVo中的name字段的值赋值给orgName; * pageIdList:responseEntity?.spacePageList?.?[#this.pageId !='']?.![pageId] * 获取响应对象responseEntity->spacePageList集合对象pageId!=''的对象的pageId集合赋值给pageIdList * #{{name:#requestVo.name,age:#root.age,type:'字符串'}} 组装map对象 * <p> * 复杂对象参考 https://zhuanlan.zhihu.com/p/174786047 */ String paramsEL() default ""; LogType logType() default LogType.OPERATION_LOG; LogDictItemEnum logDictItemEnum() default LogDictItemEnum.OPERATION_LOG00101; } package com.qz.springcloud.school.brain.core.log; import lombok.extern.slf4j.Slf4j; @Slf4j public enum LogDictItemEnum { OPERATION_LOG00101("OPERATION_LOG00101", "登录", "OPERATION_LOG001", "用户中心", "OPERATION_LOG"), OPERATION_LOG00102("OPERATION_LOG00102", "下载", "OPERATION_LOG002", "zwb", "OPERATION_LOG"); private final String dictValue; private final String dictName; private final String parentDictId; private final String parentDictName; private final String dictTypeId; LogDictItemEnum(String dictValue, String dictName, String parentDictId, String parentDictName, String dictTypeId) { this.dictValue = dictValue; this.dictName = dictName; this.parentDictId = parentDictId; this.parentDictName = parentDictName; this.dictTypeId = dictTypeId; } public String getDictValue() { return dictValue; } public String getDictName() { return dictName; } public String getParentDictId() { return parentDictId; } public String getParentDictName() { return parentDictName; } public String getDictTypeId() { return dictTypeId; } } package com.qz.springcloud.school.brain.core.log; import java.lang.reflect.Method; import java.net.InetAddress; import java.net.UnknownHostException; import java.util.ArrayList; import java.util.Collection; import java.util.Enumeration; import java.util.HashMap; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import java.util.concurrent.Executor; import java.util.concurrent.LinkedBlockingQueue; import java.util.concurrent.ThreadPoolExecutor; import java.util.concurrent.TimeUnit; import javax.servlet.http.HttpServletRequest; import org.apache.commons.collections.CollectionUtils; import org.apache.commons.lang3.StringUtils; 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.springframework.core.LocalVariableTableParameterNameDiscoverer; import org.springframework.expression.common.TemplateParserContext; import org.springframework.expression.spel.standard.SpelExpressionParser; import org.springframework.expression.spel.support.StandardEvaluationContext; import org.springframework.stereotype.Component; import org.springframework.web.context.request.RequestContextHolder; import org.springframework.web.context.request.ServletRequestAttributes; import com.qz.springcloud.school.brain.core.log.annotation.LogPoint; import lombok.extern.slf4j.Slf4j; @Component @Slf4j @Aspect public class LogPointAspect { // 定义解析器 private static final SpelExpressionParser PARSER = new SpelExpressionParser(); private static final TemplateParserContext PARSER_CONTEXT = new TemplateParserContext(); private static final LocalVariableTableParameterNameDiscoverer localVariableTable = new LocalVariableTableParameterNameDiscoverer(); /** * 定义线程池。 拒绝策略:直接拒绝,不抛出异常 */ private static final Executor executor = new ThreadPoolExecutor(Runtime.getRuntime().availableProcessors(), Runtime.getRuntime().availableProcessors() * 2, 60, TimeUnit.SECONDS, new LinkedBlockingQueue<>(500), new ThreadPoolExecutor.DiscardPolicy()); @Pointcut("@annotation(com.qz.springcloud.school.brain.core.log.annotation.LogPoint)") public void permission() { } @Around(value = "permission();") public Object around(ProceedingJoinPoint joinPoint) throws Throwable { // BuryingPointDto scBuryingPointDto = new BuryingPointDto(); Signature signature = joinPoint.getSignature(); // 参数值 Object[] args = joinPoint.getArgs(); MethodSignature methodSignature = (MethodSignature)signature; Object target = joinPoint.getTarget(); // 获取到当前执行的方法 Method method = target.getClass() .getDeclaredMethod(methodSignature.getName(), methodSignature.getParameterTypes()); // 获取注解信息 LogPoint logPoint = method.getAnnotation(LogPoint.class); Object proceed = joinPoint.proceed(); try { // 获取上下文对象 StandardEvaluationContext evaluationContext = getEvaluationContext(args, method, proceed); List<String> objList = new ArrayList<>(); String remark = null; // 判断参数是否为EL表示式 String paramsEL = logPoint.paramsEL(); if (StringUtils.isNotBlank(paramsEL)) { // 解析为EL表达式 if (paramsEL.startsWith(PARSER_CONTEXT.getExpressionPrefix()) && paramsEL.endsWith(PARSER_CONTEXT.getExpressionSuffix())) { LinkedHashMap obj = PARSER.parseExpression(paramsEL, PARSER_CONTEXT) .getValue(evaluationContext, LinkedHashMap.class); if (obj != null && obj.get("objId") != null) { objList.add((String)obj.get("objId")); } if (obj != null && obj.get("objIdList") != null) { objList.addAll((Collection<? extends String>)obj.get("objIdList")); } if (obj != null && StringUtils.isNotEmpty((String) obj.get("remark"))) { remark = (String) obj.get("remark"); } } else { // 作为普通参数 objList.add(paramsEL); } } if (CollectionUtils.isNotEmpty(objList)) { LogType logType = logPoint.logType(); LogDictItemEnum logDictItemEnum = logPoint.logDictItemEnum(); ServletRequestAttributes sra = (ServletRequestAttributes)RequestContextHolder.getRequestAttributes(); HttpServletRequest request; String ipAddress = ""; // UserLoginInfo userLoginInfo = null; Map<String, String> requestHeaders = new HashMap<>(); if (sra != null) { request = sra.getRequest(); // 获取请求的ip地址 ipAddress = getIpAddress(request); // 获取请求头信息 requestHeaders = getRequestHeaders(request); // String token = requestHeaders.get(ISystemConstants.HTTP_HEAD_ACCESS_TOKEN.toLowerCase()); // if (StringUtils.isBlank(token)) // { // return proceed; // } // userLoginInfo = SpringUtil.getBean(EcoService.class).getUserInfoByToken(token); // if (userLoginInfo == null) // { // return proceed; // } } if (LogType.OPERATION_LOG.getValue().equals(logType.getValue())) { // LogOperation logOperation = new LogOperation(); // logOperation.setObjId(id); // logOperation.setOneType(logDictItemEnum.getParentDictId()); // logOperation.setTwoType(logDictItemEnum.getDictValue()); // logOperation.setIp(finalIpAddress); // logOperation.setRemark(remarkStr); // SpringUtil.getBean(LogOperationService.class).batchInsert(logOperationList); } } } catch (Exception e) { log.error("", e); } return proceed; } /** * 填充spEL的评估上下文对象 * * @param args 代理方法的请求参数 * @param method 目标方法 * @param result 结果对象 * @return 填充请求参数的上下文对象 */ private StandardEvaluationContext getEvaluationContext(Object[] args, Method method, Object result) { // 获取参数名 String[] parameterNames = localVariableTable.getParameterNames(method); StandardEvaluationContext context = new StandardEvaluationContext(); // 填充spEL的上下文对象 if (parameterNames != null) { // 获取参数信息 // 对象信息 for (int i = 0; i < parameterNames.length; i++) { context.setVariable(parameterNames[i], args[i]); } } // 填充根对象 context.setRootObject(result); return context; } /** * 获取请求ip地址 * * @param request 请求对象 * @return 请求者的ip地址 */ public static String getIpAddress(HttpServletRequest request) { String ipAddress = request.getHeader("x-forwarded-for"); if (ipAddress == null || ipAddress.length() == 0 || "unknown".equalsIgnoreCase(ipAddress)) { ipAddress = request.getHeader("Proxy-Client-IP"); } if (ipAddress == null || ipAddress.length() == 0 || "unknown".equalsIgnoreCase(ipAddress)) { ipAddress = request.getHeader("WL-Proxy-Client-IP"); } if (ipAddress == null || ipAddress.length() == 0 || "unknown".equalsIgnoreCase(ipAddress)) { ipAddress = request.getRemoteAddr(); if ("127.0.0.1".equals(ipAddress) || "0:0:0:0:0:0:0:1".equals(ipAddress)) { // 根据网卡取本机配置的IP try { ipAddress = InetAddress.getLocalHost().getHostAddress(); } catch (UnknownHostException e) { log.error("buriedPoint getIpAddr error ", e); } } } // 对于通过多个代理的情况,第一个IP为客户端真实IP,多个IP按照','分割 // "***.***.***.***".length() if (ipAddress != null && ipAddress.length() > 15) { // = 15 if (ipAddress.indexOf(",") > 0) { ipAddress = ipAddress.substring(0, ipAddress.indexOf(",")); } } return ipAddress; } /** * 获取请求中的请求头信息 * * @param request 请求对象 * @return 请求头信息 */ public static Map<String, String> getRequestHeaders(HttpServletRequest request) { Map<String, String> headers = new HashMap<>(); Enumeration headerNames = request.getHeaderNames(); while (headerNames.hasMoreElements()) { String key = (String)headerNames.nextElement(); String value = request.getHeader(key); headers.put(key, value); } return headers; } } package com.qz.springcloud.school.brain.core.log; public enum LogType { USER_BEHAVIOR("USER_BEHAVIOR", "用户行为"), OPERATION_LOG("OPERATION_LOG", "操作日志"); LogType(String value, String name) { this.value = value; this.name = name; } private String value; private String name; public String getValue() { return value; } public String getName() { return name; } } @ComponentScan(basePackages = { "com.qz.springcloud.school.brain.core.log"}) 使用示例 @LogPoint(paramsEL = "#{{objId:#siteId}}", logType = LogType.OPERATION_LOG, logDictItemEnum = LogDictItemEnum.OPERATION_LOG00101)
编程PDF电子书免费下载: http://www.shitanlife.com/code 每天学习一点点