Skip to content

beyondsoft-log-spring3-starter 开发文档

1. 项目概述

beyondsoft-log-spring3-starter 是一个基于 Spring Boot 3.x 的日志管理 Starter,提供了全面的日志管理功能,包括操作日志、登录日志、请求日志、日志脱敏等。该模块依赖于 common-base 模块,旨在简化 Spring Boot 应用中的日志管理,提高系统的可审计性和可维护性。

2. 核心功能模块

2.1 操作日志(Audit Log)

通过注解方式记录系统中的操作日志,包括操作人、操作时间、操作类型、操作内容等信息,支持数据变更前后对比。

主要组件

  • @AuditLog:操作日志注解
  • AuditLogAspect:操作日志切面
  • BeyondSoftDataAuditLog:操作日志模型
  • AuditParser:审计日志解析器

2.2 登录日志(Login Log)

记录用户登录信息,包括登录人、登录时间、登录IP、登录状态等。

主要组件

  • @LoginLog:登录日志注解
  • LoginAspect:登录日志切面
  • BeyondSoftLoginLog:登录日志模型

2.3 请求日志(Request Log)

记录 HTTP 请求信息,包括请求URL、请求方法、请求参数、响应状态、响应时间等。

主要组件

  • RequestLogFilter:请求日志过滤器
  • BeyondSoftRequestLog:请求日志模型

2.4 日志脱敏

提供日志脱敏功能,支持多种脱敏策略,保护敏感信息。

主要组件

  • @Desensitize:日志脱敏注解
  • DesensitizationUtil:日志脱敏工具
  • DesensitizationAppender:脱敏日志Appender
  • YmlUtils:YAML配置文件工具

2.5 自定义日志 Appender

提供自定义的日志 Appender,支持控制台输出、文件输出、滚动文件输出等。

主要Appender

  • BeyondSoftConsoleAppender:控制台日志Appender
  • BeyondSoftFileAppender:文件日志Appender
  • BeyondSoftRollingFileAppender:滚动文件日志Appender

2.6 日志查询接口

提供日志查询 RESTful 接口,支持按条件查询各种日志。

主要组件

  • BeyondSoftLogQueryController:日志查询控制器
  • BeyondSoftLogService:日志服务接口

2.7 配置管理

提供灵活的配置管理,支持多种配置方式。

主要组件

  • BeyondSoftLogProperties:日志配置属性
  • BeyondSoftLogAutoConfig:日志自动配置类

3. 主要API和使用方法

3.1 操作日志

3.1.1 @AuditLog注解参数详解

参数名类型默认值详细说明
handleNameString""必填,具体业务操作名称,如 "新增用户"、"更新订单"
operationTypeOperationTypeNONE操作类型,可选值:INSERT、UPDATE、DELETE、SELECT、NONE
serviceClassClass<?>Class.class查询数据库所调用的Service类
needDefaultComparebooleanfalse是否需要默认的改动比较
idTypeClass<?>Integer.classID字段的类型
primaryKeyString"id"实体的主键字段名
batchIdParamString"ids"批量操作时,ID列表的参数名
customQueryMethodString""自定义查询方法名称
customQueryParamFieldString""自定义查询方法的参数字段名
loginNameString"username"登录日志专用,用于传入当前系统登录账号的key值

3.1.2 基本使用示例

java
// 在 Controller 方法上添加操作日志注解
@RestController
@RequestMapping("/api/users")
public class UserController {
    
    // 新增用户操作
    @PostMapping
    @AuditLog(handleName = "新增用户")
    public User addUser(@RequestBody User user) {
        return userService.save(user);
    }
    
    // 更新用户信息,记录数据变更前后的差异
    @PutMapping("/{id}")
    @AuditLog(
        handleName = "更新用户信息",
        needDefaultCompare = true,
        serviceClass = UserService.class,
        idType = Long.class,
        primaryKey = "id"
    )
    public User updateUser(@PathVariable Long id, @RequestBody User user) {
        user.setId(id);
        userService.updateById(user);
        return user;
    }
}

3.1.3 操作类型自动识别规则

当不指定 operationType 时,系统会根据方法名前缀自动识别:

方法名前缀自动识别的操作类型
save, add, create, insertINSERT
update, modifyUPDATE
delete, removeDELETE
get, find, query, list, selectSELECT

3.2 登录日志

3.2.1 基本使用示例

java
@RestController
@RequestMapping("/api/auth")
public class AuthController {
    
    @PostMapping("/login")
    @LoginLog(operationType = OperationType.INSERT, value = "username")
    public TokenInfo login(@RequestBody LoginRequest request) {
        return authService.login(request);
    }
    
    @PostMapping("/logout")
    @LoginLog(operationType = OperationType.DELETE, value = "username")
    public void logout() {
        authService.logout();
    }
}

3.3 日志脱敏

3.3.1 实体字段脱敏

java
@Data
public class User {
    private String username;
    
    @Desensitize(strategy = DesensitizeStrategy.PHONE)
    private String phone;  // 13812345678 -> 138****5678
    
    @Desensitize(strategy = DesensitizeStrategy.EMAIL)
    private String email;  // test@example.com -> t***@example.com
    
    @Desensitize(strategy = DesensitizeStrategy.ID_CARD)
    private String idCard;  // 110101199001011234 -> 110101********1234
}

3.3.2 脱敏配置文件

创建 logback-desensitize.yml 文件:

yaml
log-desensitize:
  # 是否开启脱敏
  open: true
  # 是否忽略大小写匹配
  ignore: true
  # 单规则配置
  pattern:
    phone: "(\\d{3})\\d{4}(\\d{4})"
    email: "(\\w{1})[^@]*(@.*)"
    idCard: "(\\d{6})\\d{8}(\\w{4})"
  # 多规则配置
  patterns:
    - key: "phone,mobile"
      custom:
        pattern: "(\\d{3})\\d{4}(\\d{4})"
        replace: "$1****$2"
    - key: "password,pwd"
      custom:
        pattern: ".*"
        replace: "********"

3.3.3 支持的脱敏策略

策略示例脱敏后
PHONE13812345678138****5678
EMAILtest@example.comt***@example.com
ID_CARD110101199001011234110101********1234
BANK_CARD6222021234567890123622202**********123
PASSWORD123456********
ADDRESS北京市海淀区中关村大街1号北京市海淀区********
NAME张三张*

3.4 请求日志

请求日志会自动记录所有 HTTP 请求,无需额外配置。系统会自动跳过以下请求:

  • 日志查询接口
  • SSE(Server-Sent Events)请求

请求日志输出示例

===== [RequestLog] Start | Status=200 | ResponseSize=123 | Spend=15ms =====
Caller:        admin
IP:            192.168.1.1
Location:      中国|0|广东省|深圳市|电信
Method:        GET
URI:           /api/users/1
User-Agent:    Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/100.0.4896.127 Safari/537.36
Params:        {"id":"1"}
Status:        200
Response:      {"id":1,"username":"admin","phone":"138****5678","email":"a***@example.com"}
===== [RequestLog] End | TraceId=1234567890abcdef =====

3.5 日志查询接口

3.5.1 操作日志查询

bash
# 查询操作日志
GET /api/log/audit?page=1&size=10&handleName=新增用户

# 带时间范围查询
GET /api/log/audit?page=1&size=10&startTime=2023-01-01&endTime=2023-12-31

# 按操作人查询
GET /api/log/audit?page=1&size=10&operator=admin

# 按操作类型查询
GET /api/log/audit?page=1&size=10&operation=UPDATE

3.5.2 登录日志查询

bash
# 查询登录日志
GET /api/log/login?page=1&size=10&loginName=admin

# 查询失败登录记录
GET /api/log/login?page=1&size=10&status=0

# 按IP地址查询
GET /api/log/login?page=1&size=10&ip=192.168.1.1

3.5.3 请求日志查询

bash
# 查询请求日志
GET /api/log/request?page=1&size=10&url=/api/users/*

# 查询慢请求(响应时间超过1秒)
GET /api/log/request?page=1&size=10&minResponseTime=1000

# 按状态码查询
GET /api/log/request?page=1&size=10&status=200

3.6 自定义日志 Appender

3.6.1 Logback配置示例

logback-spring.xml 中配置:

xml
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
    <!-- 控制台输出 -->
    <appender name="CONSOLE" class="com.beyondsoft.log.appender.BeyondSoftConsoleAppender">
        <encoder>
            <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
        </encoder>
    </appender>

    <!-- 文件输出 -->
    <appender name="FILE" class="com.beyondsoft.log.appender.BeyondSoftFileAppender">
        <file>logs/app.log</file>
        <encoder>
            <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
        </encoder>
    </appender>

    <!-- 脱敏日志Appender -->
    <appender name="DESENSITIZE" class="com.beyondsoft.log.appender.DesensitizationAppender">
        <appender-ref ref="CONSOLE" />
    </appender>

    <root level="info">
        <appender-ref ref="DESENSITIZE" />
        <appender-ref ref="FILE" />
    </root>
</configuration>

3.6.2 自定义Appender特性

  1. BeyondSoftConsoleAppender:增强的控制台输出,支持颜色显示
  2. BeyondSoftFileAppender:文件输出,支持自动创建目录
  3. BeyondSoftRollingFileAppender:滚动文件输出,支持按时间和大小滚动
  4. DesensitizationAppender:脱敏日志Appender,自动对敏感信息进行脱敏

3.7 日志存储架构

3.7.1 PostgreSQL自动分区

日志模块使用PostgreSQL的自动分区功能,按天创建分区表:

sql
-- 主表结构
CREATE TABLE beyond_soft_data_audit_log (
    id BIGSERIAL PRIMARY KEY,
    operator VARCHAR(255),
    modify_date TIMESTAMP,
    operation VARCHAR(50),
    handle_name VARCHAR(255),
    modify_content TEXT,
    modifier_ip VARCHAR(50),
    modifier_location VARCHAR(255),
    business_id VARCHAR(255),
    business_data_status VARCHAR(50),
    old_object JSONB,
    new_object JSONB,
    response TEXT,
    request_time TIMESTAMP,
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
) PARTITION BY RANGE (request_time);

-- 按天创建分区
CREATE TABLE beyond_soft_data_audit_log_20231230 
PARTITION OF beyond_soft_data_audit_log 
FOR VALUES FROM ('2023-12-30') TO ('2023-12-31');

3.7.2 自动分区管理

日志服务会自动管理分区:

  1. 自动创建分区:启动时自动创建未来7天的分区
  2. Caffeine缓存:缓存分区状态,24小时过期
  3. 异步写入:使用@Async注解实现异步批量写入
  4. 多数据源支持:支持MyBatis-Flex多数据源切换

4. 依赖说明

依赖项版本用途备注
common-base$公共基础模块提供基础工具和异常处理
spring-boot-starter-data-mongodb-MongoDB 支持可选,用于旧版本兼容
spring-boot-configuration-processor-配置文件处理器生成配置元数据
spring-aspects-Spring AOP 支持切面编程支持
spring-boot-starter-actuator-应用监控健康检查和指标
spring-boot-starter-web-Web 支持RESTful接口支持
hutool-http-HTTP 工具HTTP客户端工具
hutool-json-JSON 处理JSON序列化/反序列化
sa-token-core-认证授权核心用户认证和权限
sa-token-jwt-JWT 支持JWT令牌支持
sa-token-redis-jackson-Redis 支持分布式会话支持
mybatis-flex-spring-boot3-starter-MyBatis Flex 支持PostgreSQL数据访问

5. 配置说明

5.1 基本配置

application.yml 中配置日志相关属性:

yaml
# 日志模块配置
beyond-soft:
  log:
    enabled: true  # 日志功能开关
    showSql: true  # 是否显示SQL语句
    showResp: true # 是否显示响应内容
    datasourceName: ""  # 审计数据源名称(多数据源场景下使用)
    schema: ""  # 审计数据库Schema名称,建议配置如:audit
    logTypes: ["file"]  # 日志类型,默认为file

# PostgreSQL数据库配置(日志存储使用)
spring:
  datasource:
    url: jdbc:postgresql://localhost:5432/audit_db
    username: postgres
    password: password
    driver-class-name: org.postgresql.Driver

5.2 多数据源配置

yaml
# 多数据源场景配置
mybatis-flex:
  datasource:
    # 业务数据源
    master:
      url: jdbc:postgresql://localhost:5432/business_db
      username: postgres
      password: password
    # 日志数据源
    audit:
      url: jdbc:postgresql://localhost:5432/audit_db
      username: postgres
      password: password

# 日志模块配置
beyond-soft:
  log:
    enabled: true
    datasourceName: "audit"  # 指定使用audit数据源
    schema: "audit"  # 指定schema

5.3 日志级别控制

yaml
# 按模块控制日志级别
logging:
  level:
    com.beyondsoft.log: DEBUG  # 日志模块调试信息
    com.beyondsoft.log.aspect: INFO  # 切面日志
    com.beyondsoft.log.filter: WARN  # 过滤器日志

6. 注意事项

  1. 数据库兼容性:日志模块使用PostgreSQL的自动分区功能,需要PostgreSQL 10.0+版本。

  2. 数据源配置:在多数据源场景下,需要正确配置datasourceName参数。

  3. 脱敏配置:脱敏功能需要logback-desensitize.yml配置文件,确保文件路径正确。

  4. 异步处理:日志保存采用异步方式,可能会存在短暂的延迟。

  5. 分区管理:系统会自动创建未来7天的分区,确保数据库用户有创建表的权限。

  6. 索引优化:建议为常用查询字段创建索引,提高查询性能。

  7. 敏感信息:确保敏感信息已正确配置脱敏规则,避免信息泄露。

  8. 日志清理:定期清理过期日志,避免数据库空间占用过大。

  9. 版本兼容性:该模块基于Spring Boot 3.x开发,与Spring Boot 2.x不兼容。

  10. 性能考虑:在高并发场景下,建议调整批量写入的大小和异步线程池配置。

7. 常见问题

7.1 日志保存失败

问题:操作日志没有保存到数据库。

解决方案

  1. 检查数据库连接是否正常:
bash
# 测试数据库连接
psql -h localhost -p 5432 -U postgres -d audit_db
  1. 检查日志表分区是否存在:
sql
-- 查看分区表信息
SELECT schemaname, tablename, tableowner 
FROM pg_tables 
WHERE tablename LIKE 'beyond_soft_data_audit_log%';
  1. 查看应用日志中的错误信息:
yaml
logging:
  level:
    com.beyondsoft.log: DEBUG
  1. 检查BeyondSoftLogService是否正常注入:
java
// 在测试中验证服务注入
@Autowired
private BeyondSoftLogService logService;

@Test
public void testLogService() {
    assertNotNull(logService);
}

7.2 脱敏不生效

问题:日志中仍然显示敏感信息。

解决方案

  1. 检查logback-desensitize.yml配置文件是否存在:
bash
# 检查配置文件路径
ls -la src/main/resources/logback-desensitize.yml
  1. 检查脱敏配置是否正确:
yaml
# 验证配置格式
log-desensitize:
  open: true
  pattern:
    phone: "(\\d{3})\\d{4}(\\d{4})"
  1. 检查@Desensitize注解是否正确使用:
java
// 确保注解正确导入
import com.beyondsoft.log.annotation.Desensitize;
import com.beyondsoft.log.enums.DesensitizeStrategy;

@Data
public class User {
    @Desensitize(strategy = DesensitizeStrategy.PHONE)
    private String phone;
}
  1. 检查DesensitizationAppender是否配置:
xml
<!-- 确保logback配置中包含脱敏Appender -->
<appender name="DESENSITIZE" class="com.beyondsoft.log.appender.DesensitizationAppender">
    <appender-ref ref="CONSOLE" />
</appender>

7.3 性能问题

问题:系统响应变慢,日志记录影响性能。

解决方案

  1. 检查是否启用了异步日志记录:
yaml
# 确保异步配置正确
spring:
  task:
    execution:
      pool:
        core-size: 5
        max-size: 10
        queue-capacity: 100
  1. 检查数据库性能,特别是索引使用情况:
sql
-- 创建常用查询索引
CREATE INDEX idx_audit_log_request_time ON beyond_soft_data_audit_log(request_time);
CREATE INDEX idx_audit_log_operator ON beyond_soft_data_audit_log(operator);
  1. 检查日志批量写入配置:
java
// 调整批量写入大小
@Configuration
public class LogConfig {
    
    @Bean
    public BeyondSoftLogService logService(DataSource dataSource) {
        // 可以调整批量写入参数
        return new BeyondSoftLogServiceImpl(dataSource, "audit", "audit");
    }
}
  1. 考虑调整日志级别,减少不必要的日志记录:
yaml
logging:
  level:
    com.beyondsoft.log.aspect: WARN  # 减少切面日志输出

7.4 分区创建失败

问题:日志保存时报分区不存在错误。

解决方案

  1. 确保PostgreSQL版本支持分区功能(10.0+):
bash
# 查看PostgreSQL版本
psql --version
  1. 检查主表是否已创建:
sql
-- 查看表是否存在
SELECT EXISTS (
    SELECT FROM pg_tables 
    WHERE schemaname = 'public' 
    AND tablename = 'beyond_soft_data_audit_log'
);
  1. 检查数据库用户是否有创建表的权限:
sql
-- 查看当前用户权限
SELECT usename, usecreatedb, usesuper 
FROM pg_user 
WHERE usename = CURRENT_USER;
  1. 查看日志服务的schema配置是否正确:
yaml
beyond-soft:
  log:
    schema: "audit"  # 确保schema名称正确

7.5 操作类型识别错误

问题:自动识别的操作类型不正确。

解决方案

  1. 显式指定操作类型:
java
@AuditLog(
    handleName = "更新用户",
    operationType = OperationType.UPDATE  // 显式指定操作类型
)
public User updateUser(User user) {
    return userService.update(user);
}
  1. 检查方法命名是否符合规范:
java
// 正确的命名规范
public User saveUser(User user) { }      // INSERT
public User updateUser(User user) { }    // UPDATE
public void deleteUser(Long id) { }      // DELETE
public User getUser(Long id) { }         // SELECT
  1. 查看自动识别规则:
java
// 系统根据方法名前缀自动识别操作类型
// save, add, create, insert -> INSERT
// update, modify -> UPDATE
// delete, remove -> DELETE
// get, find, query, list, select -> SELECT

7.6 日志查询接口返回空

问题:日志查询接口返回空数据。

解决方案

  1. 检查查询参数是否正确:
bash
# 使用正确的查询参数
GET /api/log/audit?page=1&size=10&operator=admin&startTime=2023-01-01&endTime=2023-12-31
  1. 检查时间格式是否正确:
bash
# 正确的时间格式
GET /api/log/audit?startTime=2023-12-30T10:00:00&endTime=2023-12-30T23:59:59
  1. 检查数据库是否有数据:
sql
-- 查看日志表数据量
SELECT COUNT(*) FROM beyond_soft_data_audit_log;
  1. 检查日志服务是否正常:
java
// 测试日志服务
@Autowired
private BeyondSoftLogService logService;

@Test
public void testQueryLogs() {
    Map<String, String> condition = new HashMap<>();
    condition.put("operator", "admin");
    Page<BeyondSoftDataAuditLog> page = logService.queryMongoLogs(
        BeyondSoftDataAuditLog.class, condition, 10, 1
    );
    assertNotNull(page);
}

8. 版本历史

v1.0.0 (2025-12-30)

  • 初始版本:提供完整的日志管理功能
  • 操作日志:支持注解方式记录操作日志,支持数据变更对比
  • 登录日志:记录用户登录登出信息
  • 请求日志:自动记录HTTP请求信息
  • 日志脱敏:支持多种脱敏策略,保护敏感信息
  • PostgreSQL存储:使用PostgreSQL自动分区存储日志
  • 查询接口:提供RESTful接口查询各类日志
  • 自定义Appender:提供增强的日志输出Appender

9. 联系方式

如有问题或建议,请联系开发团队。


文档更新时间:2025-12-30
文档版本:1.0.0
模块版本:$

Copyright © 2025-present | 网站备案号:豫ICP备19038229号-1