| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162 |
- 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);
- return new RESTfulResult("500","缺乏日志必要参数"+map,"缺乏日志必要参数"+map);
- }
- //获取切点处的注解及其参数
- 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<Map<String,Object>> datas = new ArrayList<>();
- //记录到数据库
- List<LogResult> logResults=new ArrayList<>();
- //检查返回data类型
- if(result.getData() instanceof Map){
- Map<String,Object> data =(Map) result.getData();
- datas.add(data);
- }else if(result.getData() instanceof List){
- datas =(List) result.getData();
- }else{
- throw new Exception("无法处理的数据类型!");
- }
- //批量处理
- for(Map<String,Object> data : datas){
- for(int i=0 ; i<foreignKeys.length ; i++){
- if(data.get(foreignKeys[i]) != null){
- LogResult logResult=new LogResult();
- logResult.setLogId(logResultMapper.nextId());
- logResult.setForeignKeyId(DataChange.dataToBigDecimal(data.get(foreignKeys[i])));
- logResult.setForeignKeyType(foreignKeyTypes[i]);
- logResult.setLogContent(map.get("userName")+":"+result.getMessage());
- logResult.setMethodName(""+signature);
- logResult.setMethodDescription(description);
- logResult.setInsertTime(beginTime);
- logResult.setExeCost(DataChange.dataToBigDecimal(exeCost));
- logResult.setFilePath(logPrefix+format.format(beginTime));
- logResult.setInsertUsername(""+map.get("userId"));
- logResult.setRemark("自动记录");
- logResults.add(logResult);
- }
- }
- }
- if(logResults.size() > 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;
- }
- }
|