问小白 wenxiaobai
资讯
历史
科技
环境与自然
成长
游戏
财经
文学与艺术
美食
健康
家居
文化
情感
汽车
三农
军事
旅行
运动
教育
生活
星座命理

Spring Boot AOP 实现请求日志记录

创作时间:
作者:
@小白创作中心

Spring Boot AOP 实现请求日志记录

引用
CSDN
1.
https://m.blog.csdn.net/weixin_62490394/article/details/145629644

在 Web 开发中,记录请求日志是非常重要的,它不仅可以帮助我们排查问题,还能分析用户行为,优化系统性能。本篇文章将介绍如何使用Spring BootAOP(面向切面编程)实现自动记录请求日志,并将日志存入数据库。

1. 数据库设计

首先,我们需要设计一个数据库表来存储请求日志,表结构如下:

数据库表设计示例如下:

CREATE TABLE request_log (
    request_id BIGINT PRIMARY KEY,
    request_time DATETIME,
    source_ip VARCHAR(45),
    source_system VARCHAR(100),
    request_method VARCHAR(50),
    request_url VARCHAR(100),
    request_params VARCHAR(255),
    create_time DATETIME
);

2. 自定义日志注解

使用Spring AOP记录请求日志时,我们可以定义一个自定义注解 @LogRequest,用于标记需要记录日志的方法。

创建 LogRequest.java

/**
 * 日志记录注解
 *
 * @author 
 * @since: 2025/2/14
 */
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface LogRequest {
    String value() default "";
}

这个注解可以加在Controller 层的方法上,表示该方法的请求日志需要被记录。

3. 日志记录拦截器(AOP 切面)

接下来,我们使用AOP实现日志记录切面 LogRequestAspect.java

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.stereotype.Component;
import javax.servlet.http.HttpServletRequest;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import java.time.LocalDateTime;
import java.util.Arrays;
import java.util.stream.Collectors;

/**
 * 请求日志记录切面
 *
 * @author 
 * @since: 2025/2/14
 */
@Aspect
@Component
public class LogRequestAspect {
    private static final Logger log = LoggerFactory.getLogger(LogRequestAspect.class);
    @Autowired
    private RequestLogService requestLogService;
    @Around("@annotation(logRequest)")
    public Object logRequest(ProceedingJoinPoint joinPoint, LogRequest logRequest) throws Throwable {
        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        if (attributes == null) {
            log.error("无法获取 HttpServletRequest,当前线程可能不在 HTTP 请求上下文中");
            return joinPoint.proceed();
        }
        HttpServletRequest request = attributes.getRequest();
        LocalDateTime now = LocalDateTime.now();
        // 获取方法参数
        Object[] args = joinPoint.getArgs();
        String params = Arrays.stream(args)
                .map(Object::toString)
                .collect(Collectors.joining(", "));
        // 构造日志对象
        RequestLog requestLog = new RequestLog();
        requestLog.setRequestId(IdWorker.getId());  // 生成唯一 ID
        requestLog.setRequestTime(now);
        requestLog.setSourceIp(request.getRemoteAddr());
        requestLog.setSourceSystem(request.getHeader("User-Agent"));
        requestLog.setRequestMethod(request.getMethod());
        requestLog.setRequestUrl(request.getRequestURI());
        requestLog.setRequestParams(params);
        requestLog.setCreateTime(now);
        // 保存日志
        requestLogService.save(requestLog);
        return joinPoint.proceed();
    }
}

4. 日志实体类

创建 RequestLog.java,用于存储日志信息:

import java.time.LocalDateTime;
import lombok.Data;

@Data
public class RequestLog {
    private Long requestId;
    private LocalDateTime requestTime;
    private String sourceIp;
    private String sourceSystem;
    private String requestMethod;
    private String requestUrl;
    private String requestParams;
    private LocalDateTime createTime;
}

5. 日志服务类

创建 RequestLogService.java,用于存储日志:

import org.springframework.stereotype.Service;

@Service
public class RequestLogService {
    public void save(RequestLog requestLog) {
        // 这里可以将日志存入数据库
        System.out.println("日志记录:" + requestLog);
    }
}

在实际项目中,你可以将 requestLog 存入数据库,比如使用MyBatis-PlusJPA进行持久化。

6. 使用日志注解

在 Controller 方法上加上 @LogRequest 注解,就能自动记录请求日志。例如:

import org.springframework.web.bind.annotation.*;

@RestController
@RequestMapping("/api")
public class TestController {
    @LogRequest
    @GetMapping("/test")
    public String test(@RequestParam String name) {
        return "Hello, " + name;
    }
}

当访问 http://localhost:8080/api/test?name=ShenChen 时,日志会被自动记录。

7. 运行效果

运行 Spring Boot 应用后,控制台会打印日志信息,例如:

日志记录:RequestLog(
    requestId=123456789,
    requestTime=2025-02-14T14:30:00,
    sourceIp=192.168.1.100,
    sourceSystem=Mozilla/5.0 (Windows NT 10.0),
    requestMethod=GET,
    requestUrl=/api/test,
    requestParams=name=ShenChen,
    createTime=2025-02-14T14:30:00
)

如果配置了数据库存储,日志也会被保存到数据库中。

8. 总结

本篇文章介绍了如何使用Spring Boot AOP记录请求日志,包括:

  • 设计数据库表
  • 自定义 @LogRequest 注解
  • 使用 AOP 记录日志
  • 创建 RequestLog 实体类
  • 编写日志存储服务
  • 在 Controller 中使用注解

这种方式不仅能自动记录日志,还能减少代码侵入性,使日志管理更加灵活高效。

© 2023 北京元石科技有限公司 ◎ 京公网安备 11010802042949号