实现原理
通过拦截方法调用(如Controller层或Service层),在方法执行前后插入日志记录逻辑,实现业务代码与日志逻辑的解耦。
技术实现(以Spring AOP为例):
@Aspect
@Component
public class LogAspect {
@Pointcut("execution(* com.example.service.*.*(..))")
public void servicePointcut() {}
@Around("servicePointcut()")
public Object logAround(ProceedingJoinPoint joinPoint) throws Throwable {
long startTime = System.currentTimeMillis();
Object result = joinPoint.proceed();
long endTime = System.currentTimeMillis();
// 记录操作日志(方法名、参数、耗时等)
LogUtils.log(
joinPoint.getSignature().getName(),
joinPoint.getArgs(),
result,
endTime - startTime
);
return result;
}
}
优点:
缺点:
适用场景
业务逻辑层的操作记录(如接口调用、方法执行耗时)。
实现原理
通过监听数据库的Binlog日志(如MySQL),解析数据变更事件(增删改),触发日志记录。
技术流程:
RowChange
)。示例代码(Canal客户端):
CanalConnector connector = CanalConnectors.newClusterConnector(
"canal-server:11111", "example", "", "");
connector.connect();
connector.subscribe(".*\\..*"); // 订阅所有表
while (true) {
Message message = connector.getWithoutAck(100);
for (CanalEntry.Entry entry : message.getEntries()) {
CanalEntry.RowChange rowChange = CanalEntry.RowChange.parseFrom(entry.getStoreValue());
for (CanalEntry.RowData rowData : rowChange.getRowDatasList()) {
// 记录变更前后的数据
LogUtils.logDbChange(
entry.getHeader().getTableName(),
rowData.getBeforeColumnsList(),
rowData.getAfterColumnsList()
);
}
}
connector.ack(message.getId());
}
优点:
缺点:
适用场景
数据库层面的数据变更审计(如订单状态变更、用户信息修改)。
实现原理
将日志事件发送到消息队列(如Kafka、RabbitMQ),由消费者异步处理,避免阻塞主流程。
实现步骤:
kafkaTemplate.send("operation-log", "用户删除操作: ID=123");
@KafkaListener(topics = "operation-log")
public void saveLog(String logMessage) {
logRepository.save(new OperationLog(logMessage));
}
优点:
缺点:
适用场景
高并发系统或需要异步处理的日志(如用户行为埋点)。
实现原理
在业务代码中直接调用日志服务,同步写入日志。
示例代码:
public void deleteUser(Long userId) {
try {
userRepository.deleteById(userId);
// 直接记录日志
logService.log("删除用户", "用户ID=" + userId, "SUCCESS");
} catch (Exception e) {
logService.log("删除用户", "用户ID=" + userId, "FAIL: " + e.getMessage());
throw e;
}
}
优点:
缺点:
适用场景
小型项目或需要精准记录特定操作的场景。
实现原理
通过数据库触发器(如MySQL Trigger)在数据变更时自动记录日志。
示例SQL:
CREATE TRIGGER log_user_update
AFTER UPDATE ON users
FOR EACH ROW
BEGIN
INSERT INTO user_audit_log
SET user_id = OLD.id,
old_name = OLD.name,
new_name = NEW.name,
operation_time = NOW();
END;
优点:
缺点:
适用场景
对数据变更的强审计需求,且无法通过应用层实现时。
实现原理
利用ORM框架(如Hibernate、MyBatis)的拦截器监听数据操作事件。
示例(Hibernate Interceptor):
public class AuditLogInterceptor extends EmptyInterceptor {
@Override
public boolean onSave(Object entity, Serializable id, Object[] state, String[] propertyNames, Type[] types) {
logService.log("新增操作", "实体=" + entity.getClass().getName());
return super.onSave(entity, id, state, propertyNames, types);
}
}
优点:
缺点:
适用场景
使用ORM框架且需记录数据变更细节的系统。
方案 |
耦合性 |
性能影响 |
实现复杂度 |
适用场景 |
AOP |
低 |
中 |
中 |
业务方法调用追踪 |
Canal |
无 |
低 |
高 |
数据库字段级变更审计 |
消息队列 |
低 |
低 |
高 |
高并发异步日志处理 |
直接记录 |
高 |
高 |
低 |
简单场景快速实现 |
数据库触发器 |
无 |
高 |
中 |
数据库强审计需求 |
ORM事件监听 |
中 |
中 |
中 |
ORM框架下的数据操作追踪 |
选型建议:
根据团队技术栈、性能要求、审计粒度等综合选择,必要时可组合多种方案实现全面覆盖。