使用AOP记录日志

该示例展示了如何使用Spring的AOP注解(@Aspect)在SpringBoot应用中创建一个切面,拦截Controller层的方法调用,记录请求日志,包括URL、方法、参数、执行时间等信息,并将日志存储到数据库中。

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

使用Spring的AOP编程来对请求进行写入日志的一个demo。
技术栈:springboot
代码:
1、首先新建controller、dao、pojo。

@Slf4j
@RestController
@RequestMapping("/log")
public class LogController {

    @GetMapping("/insertSuccessLog")
    public Result insertSuccessLog(String name) {
        log.info("触发了成功的测试请求....");
        return Result.successResult(name);
    }

    @GetMapping("/insertErrorLog")
    public Result insertErrorLog() {
        log.info("触发了失败的测试请求....");
        int i = 0;
        try {
            i = 10 / 0;
        } catch (Exception e) {
            return Result.failResult(e.getMessage());
        }
        return Result.successResult("失败的居然成功了?");
    }

}

----------------------------------------
@Component
public interface LogDao {

    @Insert("insert into  log_controller (log_type, log_text, ip, url, method, class_method, args, result_msg, time_span) \n" +
            "values (#{logType},#{logText}, #{ip},#{url},#{method},#{classMethod},#{args},#{res},#{timeSpan}) ")
    void addLog(Log log);

}
----------------------------------------
@Data
public class Log {
    private String logType;
    private String ip;
    private String url;
    private String logText;
    private String method;
    private String classMethod;
    private String args;
    private String res;
    private long timeSpan;
    private Date createTime;
    private Date lastUpdateTime;
}

2、使用@Aspect注解进行切面编程

@Component
@Slf4j
@Aspect
public class ApiLog {
    @Value("${spring.application.name}")
    private String appName;

    @Resource
    private LogDao logDao;
    ThreadLocal<Long> startTime = new ThreadLocal<Long>();

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


    @Around(value = "controller()")
    public Object doAround(ProceedingJoinPoint joinPoint) throws Throwable {
        startTime.set(System.currentTimeMillis());
        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        HttpServletRequest request = attributes.getRequest();
        Log log = null;

        if (request.getRequestURL() != null) {
            MethodSignature signature = (MethodSignature) joinPoint.getSignature();
            log = new Log();
            log.setLogType(appName);    // 获取到YML中的配置
            // 记录下请求内容
            log.setUrl(request.getRequestURL().toString());
            log.setMethod(request.getMethod());
            log.setClassMethod(signature.getName());
            log.setLogText("暂时不写....");

        }
        //注意,如果调用joinPoint.proceed()方法,则修改的参数值不会生效,必须调用joinPoint.proceed(Object[] args)
        //获取方法参数值数组
        Object[] args = joinPoint.getArgs();
        //这个方法就是进行请求接口去了.....如果这里不返回result,则目标对象实际返回值会被置为null
        Object result = joinPoint.proceed(args);
        // 记录日志
        logMethodTime(request, log, args, result);
        return result;

    }

    private void logMethodTime(HttpServletRequest request, Log log, Object[] args, Object res) {
        // 证明不是从前端发来的请求
        if (log == null) {
            return;
        }

        String json = "";
        for (Object item : args) {
            json = JSON.toJSONString(item);
        }

        log.setArgs(json);

        if (res instanceof Result) {
            log.setRes( ((Result) res).getMsg() );
        }
        log.setIp("127.0.0.1");    // 获取ip
        log.setTimeSpan((System.currentTimeMillis() - startTime.get()));

        logDao.addLog(log);
    }
}

SQL表:

CREATE TABLE `log_controller` (
  `id` bigint NOT NULL AUTO_INCREMENT,
  `log_type` varchar(32) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NOT NULL COMMENT '日志类型,可选:service-nm,exec-cmd-log,business-log,cmd-group-log',
  `log_text` varchar(128) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci DEFAULT NULL COMMENT '日志text',
  `ip` varchar(32) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci DEFAULT NULL COMMENT 'ip',
  `url` varchar(500) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NOT NULL COMMENT 'url',
  `method` varchar(128) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NOT NULL COMMENT 'controller对应方法',
  `class_method` varchar(128) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci DEFAULT NULL,
  `args` varchar(1024) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci DEFAULT NULL COMMENT '参数',
  `result_msg` varchar(10240) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci DEFAULT NULL COMMENT '返回结果',
  `time_span` bigint NOT NULL DEFAULT '0' COMMENT '耗时(ms)',
  `create_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间 格式:YYYY-MM-DD HH:mm:ss',
  `last_update_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '最后更新时间 格式:YYYY-MM-DD HH:mm:ss',
  PRIMARY KEY (`id`) USING BTREE
);
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值