package com.steerinfo.dil.aspect; import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONObject; import com.steerinfo.dil.annotaion.LogAround; import com.steerinfo.dil.mapper.LogResultMapper; import com.steerinfo.dil.model.LogResult; import com.steerinfo.dil.util.DataChange; import com.steerinfo.framework.controller.RESTfulResult; import lombok.extern.java.Log; import org.apache.log4j.Logger; 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.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Component; import java.lang.reflect.Method; import java.text.DateFormat; import java.text.SimpleDateFormat; import java.util.*; /** * 日志 Aspect切面,编写切入点的方法 */ @Aspect @Component public class LogAspect { @Value("${prefix.logPrefix}") private String logPrefix; @Autowired LogResultMapper logResultMapper; static final Logger log = Logger.getLogger(LogAspect.class); private DateFormat format =new SimpleDateFormat("yyyy-MM-dd"); /** * 定义切入点,所有该注解为切入点 */ @Pointcut("@annotation(com.steerinfo.dil.annotaion.LogAround)") public void AroundPointCut(){} /** * 环绕通知 @Around,日志文件同时记录方法的入参出参,数据库只保留成功的出参 * @param point * @return * * @throws Throwable */ @Around("AroundPointCut()") public Object around(ProceedingJoinPoint point) throws Throwable { //获取该切点处的方法及入参 Method method = ((MethodSignature) point.getSignature()).getMethod(); Object[] requestParams = point.getArgs(); JSONObject map = null ; for(Object param:requestParams){ if(param!=null && param instanceof Map){ map = JSONObject.parseObject(JSONObject.toJSONString(param)); break; } } if(map==null || map.get("userId")==null ||map.get("userName") ==null){ log.error("缺乏日志必要参数"+map); Map resultMap = new HashMap<>(); resultMap.put("code","500"); resultMap.put("message","缺乏日志必要参数"); resultMap.put("data","缺乏日志必要参数"+map); return resultMap; } //获取切点处的注解及其参数 LogAround logAround = method.getAnnotation(LogAround.class); String[] foreignKeys = logAround.foreignKeys(); String[] foreignKeyTypes = logAround.foreignKeyTypes(); String description = logAround.description(); //获取方法签名 Signature signature = point.getSignature(); String methodName = method.getName(); log.info("执行===" + methodName + "===开始"); log.info("方法描述:" + description); log.info("方法名:" + signature); log.info("方法参数:" + map); //记录当前时间 Date beginTime = new Date(); //执行方法,并取得返回值 Object response = null; try{ response = point.proceed(); }catch (Exception e){ //记录错误日志 log.error("执行===" + methodName + "===异常:"+ e.getClass().getName()); log.error("方法描述:" + description); log.error("方法名:" + signature); log.error("方法参数:" + requestParams); throw e; } //解析返回值,记录日志 try{ RESTfulResult result = JSONObject.parseObject(JSONObject.toJSONString(response),RESTfulResult.class); //获取执行时间 long exeCost = System.currentTimeMillis() - beginTime.getTime(); if(RESTfulResult.SUCCEED.equals(result.getStatus())){ //执行成功,记录正常日志 log.info("方法返回:" + JSON.toJSONString(result)); log.info("执行时间(ms):"+exeCost); log.info("执行===" + methodName + "===成功"); try{ //data数组 List> datas = new ArrayList<>(); //记录到数据库 List logResults=new ArrayList<>(); //检查返回data类型 if(result.getData() instanceof Map){ Map data =(Map) result.getData(); datas.add(data); }else if(result.getData() instanceof List){ datas =(List) result.getData(); }else{ throw new Exception("无法处理的数据类型!"); } //批量处理 for(Map data : datas){ for(int i=0 ; i 0){ logResultMapper.batchInsert(logResults); }else{ throw new Exception("目标foreignKey不存在!"); } }catch (Exception e){ log.info("记录日志失败:"+e.getMessage()); } }else{ //记录失败日志 log.info("方法返回:" + JSON.toJSONString(result)); log.info("执行时间(ms):"+exeCost); log.info("执行===" + methodName + "===失败"); } }catch (Exception e){ //记录错误日志 log.error("===日志解析、记录失败===:\n"+ e.getMessage()); } return response; } }