日志的查看

package appapi.config;

import appapi.Vo.AppVo.AppLoginVo;
import appapi.common.ResponseBean;
import appapi.entity.Zhongjiao.SysLogEntity;
import appapi.entity.basic.UserInfo;
import appapi.service.ISysLogService;
import appapi.utils.HttpContextUtils;
import appapi.utils.IPUtils;
import appapi.utils.JwtUtil;
import appapi.utils.List2MapUtil;
import com.alibaba.fastjson.JSONObject;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.AfterThrowing;
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.core.LocalVariableTableParameterNameDiscoverer;
import org.springframework.stereotype.Component;

import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.Method;
import java.util.*;

@Aspect
@Component
@Slf4j
public class LogAspect {
@Autowired
private ISysLogService iSysLogService;

/**
 * @annotation(MyLog类的路径) 在idea中,右键自定义的MyLog类-> 点击Copy Reference
 */
@Pointcut("@annotation(appapi.config.MyLog)")
public void logPointCut() {
    log.info("------>配置织入点");
}

/**
 * 处理完请求后执行
 *
 * @param joinPoint 切点
 */
@AfterReturning(pointcut = "logPointCut()", returning = "result")
public void doAfterReturning(JoinPoint joinPoint, Object result) throws Exception {
    handleLog(joinPoint, result, null);
}

/**
 * 拦截异常操作
 *
 * @param joinPoint 切点
 * @param e         异常
 */
@AfterThrowing(value = "logPointCut()", throwing = "e")
public void doAfterThrowing(JoinPoint joinPoint, Exception e) throws Exception {
    handleLog(joinPoint, null, e);
}

private void handleLog(final JoinPoint joinPoint, Object result, final Exception e) throws Exception {


    SysLogEntity operLog = new SysLogEntity();
    ResponseBean resultData = (ResponseBean) result;
    // 获得MyLog注解
    MyLog controllerLog = getAnnotationLog(joinPoint);
    if (controllerLog == null) {
        return;
    }
    String title = controllerLog.title();
    // 获取request
    HttpServletRequest request = HttpContextUtils.getHttpServletRequest();

    Map<String, Object> data = new HashMap<>();
    if (request.getRequestURI().contains("app")&&title.contains("登录")){
        List<AppLoginVo> appData = (List<AppLoginVo>) resultData.getData();
        if (appData!=null){
            AppLoginVo vo = appData.get(0);
            data = List2MapUtil.setConditionMap(vo);
            data.put("staffAccount",vo.getUserPhone());
            data.put("staffName",vo.getUserName());
        }
    }else if (!(resultData.getData() instanceof Map)){
        data = List2MapUtil.setConditionMap(resultData.getData());
    }else {
        data = (Map<String, Object>) resultData.getData();
    }

    MethodSignature signature = (MethodSignature) joinPoint.getSignature();
    Method method = signature.getMethod();
    // 请求的方法名
    String className = joinPoint.getTarget().getClass().getName();
    String methodName = signature.getName();

    // 请求的方法参数值
    Object[] args = joinPoint.getArgs();
    // 请求的方法参数名称
    LocalVariableTableParameterNameDiscoverer u = new LocalVariableTableParameterNameDiscoverer();
    String[] paramNames = u.getParameterNames(method);
    if (args != null && paramNames != null) {
        String params = "";
        for (int i = 0; i < args.length; i++) {
            params += "  " + paramNames[i] + ": " + args[i];
        }
        operLog.setRequestParam(params);
    }
    operLog.setMethod(className + "." + methodName + "()");

    //日志类型 0=登录日志,1=操作日志,2=异常日志,3=告警日志'
    if (title.contains("登录")) {

        operLog.setOperateAccount(resultData.getCode() != 200 ? "" : data.get("staffAccount").toString());
        operLog.setOperateName(resultData.getCode() != 200 ? "" : data.get("staffName").toString());
        operLog.setLogType(0);

    } else {
        operLog.setLogType(1);
        //拿到操作人员的账号与名称,现在暂时存入的手机号
        UserInfo token = JwtUtil.getUserInfo(request.getHeader("token"));
        operLog.setOperateAccount(token.getMobile());
        operLog.setOperateName(token.getUsername());
    }
    // 操作状态(0正常 1异常)
    operLog.setOperateResult(0);
    // 操作时间
    operLog.setOperateTime(new Date());

    //code返回值为-1
    if (resultData.getCode() != 200) {
        operLog.setOperateResult(1);
        operLog.setErrorMsg(resultData.getMessage());
        operLog.setLogType(2);
    }
    

    //如果有异常则捕获返回
    if (e != null) {
        operLog.setOperateResult(1);
        operLog.setErrorMsg(e.getMessage());
        operLog.setLogType(2);
    }


    // 设置IP地址
    operLog.setIp(IPUtils.getIpAddr(request));
    // 设置uri
    operLog.setUri(request.getRequestURI());
    //操作类别
    operLog.setOperatorType(operLog.getUri().contains("app") ? 2 : 1);

    //请求方式
    operLog.setRequestMethod(request.getMethod());
    // 处理注解上的参数
    getControllerMethodDescription(joinPoint, controllerLog, operLog);

    //暂不用
    //operLog.setResult(JSONObject.toJSON(result).toString());

    // 保存数据库
    iSysLogService.saveSysLog(operLog);
}

/**
 * 是否存在注解,如果存在就获取,不存在则返回null
 *
 * @param joinPoint
 * @return
 */
private MyLog getAnnotationLog(JoinPoint joinPoint) {
    Signature signature = joinPoint.getSignature();
    MethodSignature methodSignature = (MethodSignature) signature;
    Method method = methodSignature.getMethod();
    if (method != null) {
        return method.getAnnotation(MyLog.class);
    }
    return null;
}

/**
 * 获取Controller层上MyLog注解中对方法的描述信息
 *
 * @param joinPoint 切点
 * @param myLog     自定义的注解
 * @param operLog   操作日志实体类
 */
private void getControllerMethodDescription(JoinPoint joinPoint, MyLog myLog, SysLogEntity operLog) {

    operLog.setOperateType(myLog.businessType().ordinal());
    // 设置模块标题,eg:登录
    operLog.setBizModule(myLog.title());

    // 对方法上的参数进行处理,处理完:userName=xxx,password=xxx
    // String optParam = getAnnotationValue(joinPoint, myLog.optParam());
    //operLog.setOptParam(optParam);

}

/**
 * 对方法上的参数进行处理
 *
 * @param joinPoint
 * @param name
 * @return
 */
private String getAnnotationValue(JoinPoint joinPoint, String name) {
    String paramName = name;
    // 获取方法中所有的参数
    Map<String, Object> params = getParams(joinPoint);
    // 参数是否是动态的:#{paramName}
    if (paramName.matches("^#\\{\\D*\\}")) {
        // 获取参数名,去掉#{ }
        paramName = paramName.replace("#{", "").replace("}", "");
        // 是否是复杂的参数类型:对象.参数名
        if (paramName.contains(".")) {
            String[] split = paramName.split("\\.");
            // 获取方法中对象的内容
            Object object = getValue(params, split[0]);
            // 转换为JsonObject
            JSONObject jsonObject = (JSONObject) JSONObject.toJSON(object);
            // 获取值
            Object o = jsonObject.get(split[1]);
            return String.valueOf(o);
        } else {// 简单的动态参数直接返回
            StringBuilder str = new StringBuilder();
            String[] paraNames = paramName.split(",");
            for (String paraName : paraNames) {

                String val = String.valueOf(getValue(params, paraName));
                // 组装成 userName=xxx,password=xxx,
                str.append(paraName).append("=").append(val).append(",");
            }
            // 去掉末尾的,
            if (str.toString().endsWith(",")) {
                String substring = str.substring(0, str.length() - 1);
                return substring;
            } else {
                return str.toString();
            }
        }
    }
    // 非动态参数直接返回
    return name;
}

/**
 * 获取方法上的所有参数,返回Map类型, eg: 键:"userName",值:xxx  键:"password",值:xxx
 *
 * @param joinPoint
 * @return
 */
public Map<String, Object> getParams(JoinPoint joinPoint) {
    Map<String, Object> params = new HashMap<>(8);
    // 通过切点获取方法所有参数值["zhangsan", "123456"]
    Object[] args = joinPoint.getArgs();
    // 通过切点获取方法所有参数名 eg:["userName", "password"]
    MethodSignature signature = (MethodSignature) joinPoint.getSignature();
    String[] names = signature.getParameterNames();
    for (int i = 0; i < args.length; i++) {
        params.put(names[i], args[i]);
    }
    return params;
}

/**
 * 从map中获取键为paramName的值,不存在放回null
 *
 * @param map
 * @param paramName
 * @return
 */
private Object getValue(Map<String, Object> map, String paramName) {
    for (Map.Entry<String, Object> entry : map.entrySet()) {
        if (entry.getKey().equals(paramName)) {
            return entry.getValue();
        }
    }
    return null;
}

}

@Target({ElementType.PARAMETER, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface MyLog {
// 自定义模块名,eg:登录
String title() default “”;
// 操作类型,eg:INSERT, UPDATE…
BusinessTypeEnum businessType() default BusinessTypeEnum.other;
}

  • 10
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值