一个独立开发者的审计日志平台
一个独立开发者的审计日志平台
独立开发无羡,分享从零搭建统一审计日志平台的全过程:API Key 鉴权、React + shadcn/ui 前端、Nginx + Supervisor 部署上线。
为什么要做审计日志
我的在线考试系统、云深不知处博客、一纸云深小程序——三个服务跑在同一台 ECS 上,每次排查问题都要分别登录各服务器看日志。更难受的是,查「谁在什么时候做了什么操作」全靠翻文件,效率极低。
我需要一个统一的审计日志平台:
- ✅ 各服务统一写入,集中查询
- ✅ 多维筛选(用户、操作、时间、资源)
- ✅ 部署独立,不耦合任何一个业务系统
技术选型
| 模块 | 选型 | 理由 |
|---|---|---|
| 后端框架 | Spring Boot 3.2 | 现有项目统一,复用经验 |
| ORM | MyBatis-Plus | 代码量最少 |
| 数据库 | MySQL 8.0 | RDS 已有,不加新中间件 |
| 前端 | React + shadcn/ui + TailwindCSS | 轻量、美观、组件丰富 |
| 数据库版本管理 | Liquibase | 自动建表,增量变更 |
数据库设计
两张表,非常简单:
t_operation_log 审计日志主表
| 字段 | 类型 | 说明 |
|---|---|---|
| id | bigint (自增) | 主键 |
| user_name | varchar(50) | 操作人 |
| operation_name | varchar(64) | 操作名称,如"删除试卷" |
| operation_result | tinyint | 0-成功 1-失败 2-部分成功 |
| log_type | tinyint | 0-操作日志 1-系统日志 2-安全日志 |
| log_level | tinyint | 0-重要 1-一般 2-提示 |
| server_name | varchar(64) | 服务名称 |
| resource_type | varchar(32) | 资源类型,如 exam/paper/user |
| resource_id | varchar(64) | 资源 ID |
| detail | text | 操作详情 |
| start_time | bigint | 操作开始时间 |
| end_time | bigint | 操作结束时间 |
| create_time | datetime | 记录入库时间 |
索引只有 3 个:user_name、resource_type+resource_id(联合)、create_time。审计日志写多读少,索引越少写入越快。
t_server_name_info 服务字典表
记录有哪些服务接入,前端下拉框读取用,避免 DISTINCT 扫大表。
后端 API
| 方法 | 路径 | 说明 |
|---|---|---|
| POST | /api/v1/logs | 写入一条日志 |
| GET | /api/v1/logs | 分页列表 + 多维筛选 |
| GET | /api/v1/logs/{id} | 单条详情 |
| GET | /api/v1/server-names | 服务字典列表 |
写入示例
POST/api/v1/logs{"userName":"admin","operationName":"删除试卷","operationResult":0,"logType":0,"logLevel":1,"serverName":"考试系统","resourceType":"paper","resourceId":"55","detail":"管理员 admin 删除了试卷「期末模拟考」"}鉴权:API Key
前端每次请求自动带X-Audit-Key请求头,后端 Filter 拦截校验。一开始没做,后来考虑到公网部署的风险加上的——虽然只是内部工具,但「知道地址就能用」终究不安全。
前端设计
用 React + shadcn/ui + TailwindCSS,暖色调 UI:
- 列表页:分页表格 + 按用户名/服务/类型/时间的多维筛选
- 详情页:概览卡片 + 操作详情展示
- 快捷筛选标签:操作日志 / 系统日志 / 安全日志
部署
老规矩:ECS + Nginx + Supervisor。
Maven 打成 jar 包上传到服务器,Supervisor 管理进程,Nginx 反代前端静态文件和 API,Certbot 扩域到已有 SSL 证书。
测试数据乌龙
上线后我发现测试数据还在页面上,排查半天发现是前端api.ts里把API_BASE硬编码成了localhost:8090。线上浏览器请求本地端口,读到了我本地数据库的数据。改成环境变量VITE_API_BASE后解决。
各服务接入
其他 Spring Boot 项目只需要一个RestTemplate就能接入:
restTemplate.postForObject("https://audit.wuxiannet.com/api/v1/logs",auditLogBody,Map.class);总结
审计日志平台的核心价值不在于技术多复杂,而在于「统一」。以前查问题要登录三台机器翻文件,现在一个页面全搞定。对于独立开发者来说,这种基础设施类的东西,早做早省心。
关于作者:无羡,独立开发者,专注AI应用开发。
📌 分类:全栈开发
👉 关注我获取更多技术分享
👉 个人博客:云深不知处
👉 独立开发省钱攻略:查看详情
👉 个人门户:wuxiannet.com — 我的独立开发作品全集
如果这篇文章对你有帮助,欢迎点赞、收藏、关注,你的支持是我持续创作的动力!
点击「阅读原文」查看我的独立开发笔记