zs-common-aop 日志相关技术文档
1. 模块概述
zs-common-aop 模块提供了基于 AOP 的日志记录功能,包括登录日志、操作日志和异常日志。通过注解方式,可以方便地在方法上添加日志记录功能,无需修改业务代码。
2. 目录结构
zs-common-aop/
├── src/main/java/com/zs/common/aop/
│ ├── annotation/ # 自定义注解
│ │ ├── Desensitize.java # 数据脱敏注解
│ │ ├── Log.java # 操作日志注解
│ │ └── LoginLog.java # 登录日志注解
│ ├── aspect/ # 切面实现
│ │ ├── LogAspect.java # 操作日志和异常日志切面
│ │ └── LogLoginAspect.java # 登录日志切面
│ └── config/ # 配置类
│ └── DesensitizeSerializer.java # 脱敏序列化器
└── pom.xml # Maven依赖3. 核心组件说明
3.1 日志注解
3.1.1 @Log 注解
文件路径: com.zs.common.aop.annotation.Log
用于记录操作日志的注解,可添加到方法上。
| 属性名 | 类型 | 默认值 | 描述 |
|---|---|---|---|
| module | String | "" | 功能模块名称 |
| type | OperationTypeEnum | OTHER | 操作类型 |
| description | String | "" | 功能描述 |
OperationTypeEnum 枚举值:
- ADD:新增
- UPDATE:更新
- DELETE:删除
- SELECT:查询
- EXPORT:导出
- IMPORT:导入
- OTHER:其他
3.1.2 @LoginLog 注解
文件路径: com.zs.common.aop.annotation.LoginLog
用于记录登录日志的注解,可添加到登录相关方法上。
| 属性名 | 类型 | 默认值 | 描述 |
|---|---|---|---|
| value | int | 1 | 登录状态(1:成功,2:失败) |
3.2 日志切面
3.2.1 LogAspect 切面
文件路径: com.zs.common.aop.aspect.LogAspect
处理操作日志和异常日志的切面类。
核心方法:
logOperationPointCut():定义操作日志切入点before():前置通知,记录方法开始时间afterReturning():返回通知,记录操作日志afterThrowing():异常通知,记录异常日志saveLogOperation():异步保存操作日志saveLogError():异步保存异常日志
操作日志记录内容:
- 用户名
- 模块名称
- IP地址
- 操作类型
- 操作描述
- 请求方法
- 请求路径
- 请求参数
- 响应状态码
- 响应消息
- 操作时长
- 创建时间
异常日志记录内容:
- 用户名
- 模块名称
- IP地址
- 异常类型
- 异常信息
- 请求方法
- 请求路径
- 请求参数
- 创建时间
3.2.2 LogLoginAspect 切面
文件路径: com.zs.common.aop.aspect.LogLoginAspect
处理登录日志的切面类。
核心方法:
loginPointCut():定义登录日志切入点around():环绕通知,执行目标方法并记录登录日志saveLoginLog():异步保存登录日志
登录日志记录内容:
- 用户名
- 登录时间
- IP地址
- 城市信息
- User-Agent
- 登录状态
- 失败原因(如果登录失败)
- 浏览器信息
- 操作系统信息
4. 功能详解
4.1 操作日志功能
4.1.1 工作原理
- 在需要记录操作日志的方法上添加
@Log注解 - 当方法被调用时,
LogAspect切面的before()方法记录开始时间 - 方法执行完成后,
afterReturning()方法被调用 saveLogOperation()异步方法保存操作日志到数据库
4.1.2 支持的场景
- 增删改查操作
- 导出导入操作
- 其他需要记录的业务操作
4.2 异常日志功能
4.2.1 工作原理
- 在需要记录异常日志的方法上添加
@Log注解 - 当方法执行过程中抛出异常时,
afterThrowing()方法被调用 saveLogError()异步方法保存异常日志到数据库
4.2.2 支持的场景
- 业务逻辑异常
- 系统异常
- 数据库异常
- 其他类型的异常
4.3 登录日志功能
4.3.1 工作原理
- 在登录相关方法上添加
@LoginLog注解 - 当方法被调用时,
around()方法执行目标方法 saveLoginLog()异步方法保存登录日志到数据库
4.3.2 支持的场景
- 用户登录成功
- 用户登录失败
- 用户登出
5. 使用示例
5.1 操作日志示例
java
@PostMapping("/add")
@Log(module = "用户管理", type = OperationTypeEnum.ADD, description = "新增用户")
public Result<Void> addUser(@Validated @RequestBody UserAddParams params) {
userService.addUser(params);
return Result.ok();
}5.2 异常日志示例
java
@GetMapping("/detail/{id}")
@Log(module = "用户管理", type = OperationTypeEnum.SELECT, description = "查询用户详情")
public Result<UserVO> getUserDetail(@PathVariable Long id) {
User user = userService.getUserById(id);
if (user == null) {
throw new ZsException(ErrorCode.USER_NOT_FOUND);
}
return Result.ok(UserVO.convert(user));
}5.3 登录日志示例
java
@Override
public void authenticate(Authentication authentication, HttpServletRequest request, HttpServletResponse response) {
// 登录逻辑
// ...
}
@LoginLog(value = 1) // 登录成功
public void onAuthenticationSuccess(Authentication authentication, HttpServletRequest request, HttpServletResponse response) {
// 登录成功处理
// ...
}
@LoginLog(value = 2) // 登录失败
public void onAuthenticationFailure(AuthenticationException exception, HttpServletRequest request, HttpServletResponse response) {
// 登录失败处理
// ...
}6. 技术实现
6.1 AOP 实现
使用 Spring AOP 框架实现,通过注解方式定义切点,使用环绕通知、前置通知、返回通知和异常通知处理日志记录。
6.2 异步处理
日志保存采用异步方式,通过 @Async 注解实现,避免影响业务方法的执行效率。
6.3 IP 地址处理
使用 IpUtils 工具类获取 IP 地址和城市信息,支持 IPv4 和 IPv6。
6.4 浏览器和操作系统识别
使用 Hutool 工具库的 UserAgentUtil 解析 User-Agent 字符串,获取浏览器和操作系统信息。