springboot 日志类切面,接口成功记录日志,失败不记录

springboot 日志类切面,接口成功记录日志,失败不记录

自定义一个注解方法



import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

/**
 * <描述> 标记需要记录日志的方法
 *
 */
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface LogOperation {
    String detail() default "";//内容

    String type() default "";//类型

    String modName() default "";//模块名称

    boolean add() default true;

}

主要的切面类

我这里获取了Authentication 用于添加farmId和userId ,可以根据自己的方法替换或删除这部分
我其他接口统一返回用了 自定义的返回类Ret,所以这里判断了Ret 返回状态


import com.alibaba.fastjson.JSON;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Component;
import org.springframework.validation.BeanPropertyBindingResult;

import java.util.ArrayList;
import java.util.List;

/**
 * 日志-切面类
 */
@Aspect
@Component
@Slf4j
public class LoggingAspect {
    @Autowired
    private SysLogService sysLogService;

    //暂定设置默认的参数
    private static final int DEFAULT_FARM_ID = 0;
    private static final int DEFAULT_USER_ID = 0;

    @Around("@annotation(logOperation)")
    public Object logAround(ProceedingJoinPoint joinPoint, LogOperation logOperation) throws Throwable {
        log.info("--------------------记录日志开始------------------------------------");
        //初始化日志类
        SysLog sysLog = new SysLog();
        long startTime = System.currentTimeMillis();

        try {
            // 获取 Authentication 用于添加farmId和userId
            Authentication auth = SecurityContextHolder.getContext().getAuthentication();
            SysAccount account = (auth != null && auth.getPrincipal() instanceof SysAccount) ?
                    (SysAccount) auth.getPrincipal() : null;

            if (account != null) {
                sysLog.setFarmId(account.getFarmId());
                sysLog.setUserId(account.getUserId());
            } else {
                log.warn("Authentication 或 principal 为 null,无法获取 SysAccount,设置默认参数 0 ");
                sysLog.setFarmId(DEFAULT_FARM_ID);
                sysLog.setUserId(DEFAULT_USER_ID);
            }

            // 检查 LogOperation 的各个字段是否为空
            String text = (logOperation != null && logOperation.detail() != null) ?
                    logOperation.detail() : "";
            String type = (logOperation != null && logOperation.type() != null) ?
                    logOperation.type() : "";
            String modName = (logOperation != null && logOperation.modName() != null) ?
                    logOperation.modName() : "";

            sysLog.setType(type);
            sysLog.setModName(modName);
            sysLog.setDetail(text);

            // 执行目标方法并捕获结果
            Object result = joinPoint.proceed();

            // 接口统一返回的都是Ret,这里检查返回结果是否为 Ret,并判断状态
            if (result instanceof Ret) {
                Ret ret = (Ret) result;

                // 如果返回状态为 fail,则不记录日志
                if (ret.isFail()) {
                    log.info("--------------------记录日志结束(请求失败,不记录日志)------------------------------------");
                    return result; // 返回原结果,不进行日志记录
                }

                // 如果状态为 ok,则记录日志
                Object[] args = joinPoint.getArgs(); // 获取方法参数
                List<String> filteredArgs = new ArrayList<>();

                for (Object arg : args) {
                    if (!(arg instanceof Authentication || arg instanceof BeanPropertyBindingResult)) {
                        filteredArgs.add(arg != null ? arg.toString() : "null");
                    }
                }

                String jsonArgs;
                try {
                    jsonArgs = JSON.toJSONString(filteredArgs); // 转换参数为 JSON 字符串
                } catch (Exception e) {
                    log.error("JSON转换出错: {}", e.getMessage());
                    jsonArgs = "无法序列化参数"; // 设定默认值
                }

                sysLog.setDetail(text + "-参数:" + jsonArgs);
                //执行日志添加
                sysLogService.save(sysLog);
            } else {
                log.warn("返回结果不是 Ret 类型,无法判断状态");
            }

            return result;

        } catch (Throwable throwable) {
            log.error("日志记录失败: {}", throwable.getMessage(), throwable);
            throw throwable;
        } finally {
            //记录执行时间已经标志结束
            long endTime = System.currentTimeMillis();
            log.info("方法执行时间:{} ms", endTime - startTime);
            log.info("--------------------记录日志结束------------------------------------");
        }
    }
}

具体调用逻辑

也可以根据需求加注解内的字段
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值