基于AOP的日志保存

本文介绍了一种使用AOP(面向切面编程)在Java应用中实现系统操作日志记录的方法。通过定义注解和切面,可以自动记录方法调用的日志,包括操作类型、用户、IP地址、浏览器信息等,适用于增删改查和定时任务的日志记录。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface SystemOperLog {

    /**
     * 其他
     */
    int LOG_TYPE_OTHER = 0;

    /**
     * 新增
     */
    int LOG_TYPE_INSERT = 1;
    /**
     * 更新
     */
    int LOG_TYPE_UPDATE = 2;
    /**
     * 删除
     */
    int LOG_TYPE_DELETE = 3;
    /**
     * 定时任务
     */
    int LOG_TYPE_TASK = 4;

    
    /**
     * 日志描述
     * @return
     */
    String value() default "";


    /**
     * 日志类型 0:其他,1:新增,2:更新,3:删除,4:定时任务
     * @return
     */
    int logType() default 0;

    /**
     * 是否保存实体对象到日志内容中
     * @return
     */
    boolean isSaveEntity() default true;

    /**
     * 是否将日志保存到数据库
     * @return
     */
    boolean isSaveDb() default true;

    /**
     * 指定第几个参数保存到数据库
     * @return
     */
    int paramIndex() default -1;

    /**
     * 指定第几个参数的名称
     * @return
     */
    String paramName() default "";

    /**
     * 根据主键上的值判断是新增还是更新
     * @return
     */
    String pkName() default "";

}
@Aspect
@Component
public class SystemOperLogAspect {

    private final static Logger logger = LoggerFactory.getLogger(SystemOperLogAspect.class);

    public SystemOperLogAspect(){
        logger.info("###############################SystemOperLogAspect iinitialize#################################");
    }

    @Autowired
    private SystemOperLogDubboService systemOperLogDubboService;

    @Pointcut("@annotation(com.vanke.plat.aop.annotation.SystemOperLog)")
    public void logPointCut() {
    }

    @Around("logPointCut()")
    public Object around(ProceedingJoinPoint joinPoint) throws Throwable {
        long beginTime = System.currentTimeMillis();

        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        Method method = signature.getMethod();
        SystemOperLog systemOperLog = method.getAnnotation(SystemOperLog.class);
        boolean isInsert = isInsert(joinPoint, systemOperLog);

        // 执行方法
        Object result = joinPoint.proceed();
        try{
            //进行日志记录
            saveLog(joinPoint,systemOperLog,beginTime,isInsert);
        }catch (Exception e){
            logger.error("saveLog error:{}",e);
        }
        return result;
    }

    /**
     * 判断是不是新增
     * @param joinPoint
     * @param systemOperLog
     * @return
     */
    private boolean isInsert(ProceedingJoinPoint joinPoint, SystemOperLog systemOperLog) {
        boolean isInsert = false;
        try{
            String pkName = systemOperLog.pkName();
            int paramIndex = systemOperLog.paramIndex();
            //获取参数列表
            Object[] argsObj = joinPoint.getArgs();
            if(SystemOperLog.LOG_TYPE_UPDATE == systemOperLog.logType()
                    && paramIndex >= 0
                    && argsObj != null
                    && argsObj.length >= paramIndex
                    && StringUtils.isNotBlank(pkName)){
                Object argObj = argsObj[paramIndex];
                if(argObj != null){
                    if(argObj instanceof BasePlatEntity){
                        BasePlatEntity basePlatEntity = (BasePlatEntity)(argObj);
                        if(StringUtils.isBlank(basePlatEntity.getId())){
                            isInsert = true;
                        }
                    }else if(!(argObj instanceof String)){
                        JSONObject jsonObject = JSONUtil.parseObj(argObj);
                        if(StringUtils.isBlank(jsonObject.getStr(pkName))){
                            isInsert = true;
                        }
                    }
                }
            }
        }catch (Exception e){
            logger.error("around error:{}",e.getMessage());
        }
        return isInsert;
    }

    private void saveLog(ProceedingJoinPoint joinPoint,SystemOperLog systemOperLog,long beginTime,boolean isInsert) {

        int logType = systemOperLog.logType();
        boolean isSaveDb = systemOperLog.isSaveDb();
        boolean isSaveEntity = systemOperLog.isSaveEntity();
        String logValue = systemOperLog.value();

        Date date = new Date();
        SystemOperLogEntity systemOperLogEntity = new SystemOperLogEntity();
        systemOperLogEntity.setOperateDate(date);
        systemOperLogEntity.setLogId(DateFormatUtils.format(date, CommonConstants.DATE_PATTERN_17));
        String username = (String) SecurityUtils.getSubject().getPrincipal();
        String remoteIp = HttpServletUtil.getIpAddress();//请求IP
        String browser = HttpServletUtil.getBrowser();   //浏览器及操作系统
        systemOperLogEntity.setOperateUser(username);
        systemOperLogEntity.setIp(remoteIp);
        systemOperLogEntity.setBrowser(browser);
        systemOperLogEntity.setOperateType(logType);
        systemOperLogEntity.setOperateMsg(logValue);
        if(isSaveDb){
            if(isSaveEntity){
                generateEntityInfo(joinPoint, systemOperLog, systemOperLogEntity,isInsert);
            }
            systemOperLogDubboService.saveData(systemOperLogEntity);
        }else {
            // 日志记录到日志文件中
            logger.info("use time:{},{}",(System.currentTimeMillis()-beginTime),JSONUtil.parseObj(systemOperLogEntity).toString());
        }
    }

    /**
     * 生成实体JSON信息
     * @param joinPoint
     * @param systemOperLog
     * @param systemOperLogEntity
     */
    private void generateEntityInfo(ProceedingJoinPoint joinPoint, SystemOperLog systemOperLog, SystemOperLogEntity systemOperLogEntity,boolean isInsert) {
        int paramIndex = systemOperLog.paramIndex();
        //获取参数列表
        Object[] argsObj = joinPoint.getArgs();
        if(paramIndex >= 0 && argsObj != null && argsObj.length >= paramIndex){
            Object argObj = argsObj[paramIndex];
            if(argObj != null){
                try{
                    String content = null;
                    if(argObj instanceof String){
                        String paramName = systemOperLog.paramName();
                        if(StringUtils.isNotBlank(paramName)){
                            content = paramName+":"+argObj.toString();
                        }else{
                            content = argObj.toString();
                        }
                        String pkValue = argObj.toString();
                        if(pkValue.length()>32){
                            systemOperLogEntity.setLogId(pkValue.substring(0,32));
                        }else{
                            systemOperLogEntity.setLogId(pkValue);
                        }

                    }else{
                        JSONObject jsonObject = JSONUtil.parseObj(argObj);
                        String pkName = systemOperLog.pkName();
                        if(StringUtils.isNotBlank(pkName)){//根据所提供的主键判断是否是新增
                            String pkValue = jsonObject.getStr(pkName);
                            if(StringUtils.isNotBlank(pkValue)){
                                if(pkValue.length()>32){
                                    systemOperLogEntity.setLogId(pkValue.substring(0,32));
                                }else{
                                    systemOperLogEntity.setLogId(pkValue);
                                }
                            }
                            if(isInsert){
                                systemOperLogEntity.setOperateType(SystemOperLog.LOG_TYPE_INSERT);
                            }
                        }
                        content = jsonObject.toJSONString(0);
                    }
                    systemOperLogEntity.setContent(content);
                }catch (Exception e){
                    logger.warn("parese obj error:{}",argObj);
                }
            }
        }
    }
}

 

https://blog.youkuaiyun.com/weixin_42184707/article/details/80348103

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值