springboot 使用AOP切面保存操作日志

项目场景:

采用AOP的方式,拦截请求,写入日志


切面代码:


import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.util.HashMap;
import java.util.Map;

@Aspect
@Component
@Slf4j
public class RSAAspect {

    @Autowired
    private LogService logService;

    @Pointcut("execution(* com..*.controller..*.*(..))")
    public void webRequest() {
    }



    @Around("webRequest()")
    public Object logExecutionTime(ProceedingJoinPoint joinPoint) throws Throwable {
        Object proceed = joinPoint.proceed();
        Map<String, Object>  joinPointMap= new HashMap<>();
        String apiName = joinPoint.getSignature().getName();
        joinPointMap.put("apiName",apiName);
        joinPointMap.put("className",joinPoint.getTarget().getClass().getName());
        joinPointMap.put("signature",joinPoint.getSignature());
        joinPointMap.put("proceed",proceed);
        // 获取请求信息
        HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
        //保存操作日志
        logService.saveLogAction(joinPointMap,request);
        return proceed;
    }

}

业务代码:


    public void saveLogAction( Map<String, Object>  joinPointMap, HttpServletRequest request) {
        try {
            //接口名
            String apiName = joinPointMap.get("apiName").toString();
            //类名
            String className =  joinPointMap.get("className").toString();
            String lastClassName = className.substring(className.lastIndexOf(".") + 1);
            //get/post...
            String requestMethod =  request.getMethod();
            // 获取客户端IP地址
            String clientIpAddress = request.getRemoteAddr();
            // 获取服务端IP地址(注意:这通常是负载均衡器或前端服务器的IP)
            String serverIpAddress = request.getLocalAddr();
            // 获取服务器端口
            String serverPort = String.valueOf(request.getLocalPort());
            LogAction logAction = new LogAction();
            logAction.setClientIp(clientIpAddress);
            logAction.setServerIp(serverIpAddress);
            logAction.setServerPort(serverPort);
            logAction.setActionTime(LocalDateTime.now());
            logAction.setLogId(getUUID());
            logAction.setSessionId("");
            logAction.setSystemName(ConMap.SYSTEM_NAME);
            logAction.setModuleName("");
            logAction.setActionName(getActionNameByMethod(requestMethod,apiName));
            if(ConMap.containsKey(lastClassName)) {
                //Controller对应的模块名称
                String lastName = ConMap.getValue(lastClassName);
                logAction.setModuleName(lastName);
                //操作描述 xx对xxx进行xxx操作
                StringBuilder sb = new StringBuilder();
                sb.append("对");
                sb.append(lastName);
                sb.append("进行");
                sb.append(logAction.getActionName());
                sb.append("操作");
                logAction.setActionDesc(sb.toString());
            }else {
                logAction.setActionDesc(logAction.getActionName());
            }
            logAction.setActionCmd(className+"."+apiName);
            logAction.setActionNum(0);
            logAction.setActionResult(1);
            String sessionId = StpUtil.getTokenValue();
            logAction.setSessionId(sessionId);
            // 返回结果
            Object proceed = joinPointMap.get("proceed");
            if (proceed instanceof R) {
                R r = (R) proceed;
                if(r.getCode().equals("200")){
                    logAction.setActionResult(0);
                    Object obj = r.getData();
                    logAction.setActionNum(getDataTotal(obj));
                }
            }
            if(StpUtil.isLogin()){
                //当前人信息
                AppUser userInfo = UserInfoUtil.getUserInfo();
                if(userInfo!=null){
                    logAction.setUserId(userInfo.getId());
                    logAction.setUserCode(userInfo.getUserCode());
                    logAction.setUserName(userInfo.getUserName());
                    logAction.setTenantId(userInfo.getTenantId());
                    logAction.setActionDesc(userInfo.getUserCode()+logAction.getActionDesc());
                }
            }
            this.baseMapper.insert(logAction);
        }catch (Throwable e) {
            log.error("记录操作日志异常", e);
        }

    }

    private String getActionNameByMethod(String requestMethod, String apiName) {
        String  actionName =  getActionNameByApi(apiName);
        if(StringUtils.isEmpty(actionName)) {
            switch (requestMethod) {
                case "GET":
                case "get":
                    actionName = "查询";
                    break;
                case "DELETE":
                case "delete":
                    actionName = "删除";
                    break;
                default:
                    actionName = "新增或修改";
            }
        }
        return actionName;
    }

    /*获取数据量*/
    private Integer getDataTotal(Object obj) {
        if (obj != null) {
            if (obj instanceof List) {
                log.debug("Object is a List.");
                return ((List<Object>) obj).size();
            } else if (obj instanceof Map ) {
                log.debug("Object is a Map.");
                Map<String, Object> map = (Map<String, Object>) obj;
                return map.get("total") ==null ? 0 : Integer.valueOf(map.get("total").toString()) ;
            } else if (obj instanceof Page) {
                log.debug("Object is a Page.");
                Page<?> page = (Page<?>) obj;
               return (int) page.getTotal();
            }

        }
        return 0;

    }


    private String getActionNameByApi(String apiName) {
        String name = "";
        if(apiName.contains("login") || apiName.contains("doLogin")){
            name = "登录";
        }else if(apiName.contains("logout")){
            name = "登出";
        }else if(apiName.contains("page") || apiName.contains("get") || apiName.contains("select")
                || apiName.contains("list") || apiName.contains("search")){
            name = "查询";
        }else if(apiName.contains("create") || apiName.contains("add") || apiName.contains("save")){
            name = "新增";
        }else if(apiName.contains("update")){
            name = "修改";
        }else if(apiName.contains("delete")){
            name = "删除";
        }else if(apiName.contains("export")){
            name = "导出";
        }else if(apiName.contains("import") ){
            name = "导入";
        }else if(apiName.contains("upload") ){
            name = "上传";
        }
        return name;
    }


    private String getUUID() {
        String uuid = UUID.randomUUID().toString();
        return uuid.replaceAll("-", "");
    }

业务代码:

import java.util.HashMap;
import java.util.Map;

public class ConMap {


    //根据业务系统自己命名
    public static  String SYSTEM_NAME ="运营系统";


    // 创建一个静态的HashMap来存储固定的键值对
    private static final Map<String, String> FIXED_MAP = new HashMap<>();

    // 静态初始化块,用于初始化FIXED_MAP
    static {
        /*auth*/
        FIXED_MAP.put("AppDeptController", "部门");
        FIXED_MAP.put("AppRoleController", "角色");
        FIXED_MAP.put("AppTenantController", "租户");
        FIXED_MAP.put("AppUserController", "用户");
        // 添加更多固定的键值对...
    }

    // 私有构造器,防止外部实例化
    private ConMap() {
    }

    /**
     * 获取指定的key对应的value
     *
     * @param key 要查找的key
     * @return 如果key存在,则返回对应的value;否则返回null
     */
    public static String getValue(String key) {
        return FIXED_MAP.get(key);
    }


    /**
     * 检查Map中是否包含指定的key
     *
     * @param key 要检查的key
     * @return 如果Map包含指定的key,则返回true;否则返回false
     */
    public static boolean containsKey(String key) {
        return FIXED_MAP.containsKey(key);
    }

}

操作类:

/**
 * <p>
 * 操作日志
 * </p>
 */
@Getter
@Setter
@TableName("tbl_log")
public class LogAction extends CrudEntity  {

    private static final long serialVersionUID = 1L;

    @TableId(type = IdType.AUTO)
    private Long id;
    /**
     * 租户id
     */
    private Long tenantId;
    /**
     * 用户id
     */
    private Long userId;
    /**
     * 用户帐号
     */
    private String userCode;
    /**
     * 用户姓名
     */
    private String userName;
    /**
     * 客户端IP地址:用户登录所使用的客户端IP
     *
     */
    private String clientIp;
    /**
     * 服务端IP地址:应用服务器ip地址
     */
    private String serverIp;
    /**
     * 服务器端端口
     */
    private String serverPort;
    /**
     * 操作时间
     */
    @JsonFormat(pattern="yyyy-MM-dd HH:mm:ss")
    private LocalDateTime actionTime;
    /**
     *日志ID
     */
    private String logId;
    /**
     *会话ID:关联应用系统接口调用日志的标识
     */
    private String sessionId;
    /**
     * 系统名称,三级系统名称“辽宁联通服务营销运营系统”
     */
    private String systemName;
    /**
     * 模块名称 如:开户、积分调整、开通xx套餐等。如果此业务涉敏,需与“涉敏数据资产”
     */
    private String moduleName;
    /**
     *操作动作名称,如:新增、查询、修改、删除、导出、登录、登出
     */
    private String actionName;
    /**
     *操作描述:如:Xxx(操作帐号)对(操作对象xxx(可为手机号))进行xxx操作
     */
    private String actionDesc;
    /**
     * 操作命令,记录接口请求的方法com.holycrm.hollycas.record.controller.queryRecord
     */
    private String actionCmd;
    /**
     * 操作数量
     */
    private Integer actionNum;
    /**
     * 操作结果,0:成功,1:失败
     */
    private Integer actionResult;

}

sql脚本:

CREATE TABLE `tbl_log` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT,
  `tenant_id` bigint(20) DEFAULT NULL COMMENT '租户id',
  `user_id` varchar(50) DEFAULT NULL COMMENT '用户id',
  `user_code` varchar(50) DEFAULT NULL COMMENT '用户帐号',
  `user_name` varchar(50) DEFAULT NULL COMMENT '用户姓名',
  `client_ip` varchar(50) DEFAULT NULL COMMENT '客户端IP地址:用户登录所使用的客户端IP',
  `server_ip` varchar(50) DEFAULT NULL COMMENT '服务端IP地址:应用服务器ip地址',
  `server_port` varchar(20) DEFAULT NULL COMMENT '服务器端端口',
  `action_time` datetime DEFAULT NULL COMMENT '操作时间',
  `log_id` varchar(50) DEFAULT NULL COMMENT '日志ID',
  `session_id` varchar(50) DEFAULT NULL COMMENT '会话ID:关联应用系统接口调用日志的标识',
  `system_name` varchar(50) DEFAULT NULL COMMENT '系统名称,三级系统名称“辽宁联通服务营销运营系统”',
  `module_name` varchar(50) DEFAULT NULL COMMENT '模块名称,如crm系统:开户、积分调整、开通xx套餐等。如果此业务涉敏,需与“涉敏数据资产”',
  `action_name` varchar(50) DEFAULT NULL COMMENT '操作动作名称,如:新增、查询、修改、删除、导出、登录、登出',
  `action_desc` varchar(500) DEFAULT NULL COMMENT '操作描述:如:Xxx(操作帐号)对(操作对象xxx(可为手机号))进行xxx操作',
  `action_cmd` varchar(500) DEFAULT NULL COMMENT '操作命令,记录接口请求的方法com.holycrm.hollycas.record.controller.queryRecord',
  `action_num` int(10) DEFAULT NULL COMMENT '操作数量',
  `action_result` int(10) DEFAULT NULL COMMENT '操作结果:0-成功1-失败',
  `update_by` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '最后更新人',
  `update_at` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '最后更新时间',
  `create_by` varchar(50) DEFAULT NULL COMMENT '最后更新人',
  `create_at` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '最后更新时间',
  `create_dept` bigint(20) DEFAULT NULL COMMENT '创建人部门id',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='操作日志';

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值