本提交为 .git 对象库损坏后的重建提交,内容等价于原先三个本地提交 (5e2fd4c2 / 57a53c98 / 5d7e1873)的累积结果,未做任何额外改动。 一、docs 结构整改(整改 #14) 根因:重构时新结构为 untracked 文件,执行 git stash(未带 -u)未纳入, 随后 git reset 拉回 HEAD 旧 tracked 树,导致旧树复活、新旧两棵目录 树并存于 docs/,共 791 文件、双分类体系冲突。 修复动作: - b2 同名异主题文件改名迁移保全 9 个 - C 类 39 个孤立文件按主题正确归类 - A/B1 类 222 个重复文件删除(新结构已有内容副本) - 9 个旧独有空目录删除 - 270 处内部引用按 verified 映射改写 - 整改记录 #14 登记于 04-运维文档/部署运维 结果:docs 791 → 569 文件,顶层仅规范 8 类 + 治理文件,单树恢复。 残留:约 20 处指向从未存在文件的陈旧死链,归入独立文档卫生任务。 二、compose 双目录对齐(消除踩坑 A) - docker-compose.yml:nginx 前端挂载全部由根目录 frontend-*/dist 改为 src/frontend-*/dist(h5 / agent / admin / terminal) - docker-compose.dev.yml:dev 服务 build context 与卷同步改 src/ - 效果:本地 docker compose up 不再把根目录 stale dist 挂回, 与线上一致,分叉隐患消除(已 docker compose config 校验通过) 防复发铁律: - 重构须提交;仓库修复须 git stash -u 或先 commit - 新结构须 git add 并提交,避免再次 untracked 复活 - H5 改动只动 src/frontend-h5/,禁改根目录遗留 frontend-*/
16 KiB
系统日志与审计日志 — 产品 + 设计文档
版本:v1.0 | 日期:2026-07-09 | 作者:许清楚(产品经理)| 关联文档:PRD v1.2 / 架构设计 v1.3 / 安全审计报告-日志结构化 / 管理员手册 §10.2
一句话:管理后台长期存在 5 类「日志」机制概念混淆,本文档统一 A/B/C/D/E 的定义、边界、接口与权限,并落地用户(宋献,税友集团 IT 支持组长)已拍板的 5 项决策。
1. 概述:为什么要有这份文档
管理后台经代码与文档盘点,确认存在 5 类被笼统称为「日志」的机制,但其记录对象、落点、读者、用途各不相同,长期造成概念混淆与维护歧义:
- A. 系统日志 = 配置变更历史(记「配置项改了什么值」)
- B. 操作日志 / 审计日志 = 安全行为事件(记「谁做了什么安全相关动作」)
- C. 自动化动作日志 = 外部系统调用出入参(排障 + 审计)
- D. 运行期结构化日志 = 应用运行 stdout 日志(排障)
- E. 会话 / 消息记录 = 业务主数据(非独立日志子系统)
其中 A 与 B 最易混淆(都涉及「配置变更」),当前 A 页面无任何筛选控件;D 运行期日志查看(决策 4)已落地(后端接口 GET /api/admin/runtime-logs + 前端 RuntimeLogs.vue + 部署 RUNTIME_LOG_DIR bind mount)。本文档目标:
- 给五类日志一个统一定义与命名,消除歧义;
- 明确 A vs B 的关键差异与双写边界;
- 将用户 5 项决策产品化为可验收的规格;
- 作为下一阶段架构师(高见远)的输入,自包含地描述接口、字段、权限。
2. 五类日志总览表
| 编号 | 内部名称 | 管理后台 UI 命名 | 落点(表 / 存储) | 核心用途 | 主要读者 | 实现状态 |
|---|---|---|---|---|---|---|
| A | 系统日志(配置变更历史) | 配置变更历史 | config_change_logs |
记录配置项前后值 diff | 管理员 / 运维 | 已实现(前端无筛选) |
| B | 操作日志 / 审计日志 | 安全审计日志 | audit_logs |
记录安全行为事件 | 管理员 / 审计员 | 已实现(部分事件待补) |
| C | 自动化动作日志 | 自动化动作日志 | auto_action_logs |
外部系统调用出入参全量落表 | 运维 / 开发 | 已实现(落表为主) |
| D | 运行期结构化日志 | 运行期日志查看 | stdout → Docker 文件 | 应用运行排障 | 运维 / 开发 | 已落地(前后端 + 部署) |
| E | 会话 / 消息记录 | 会话与消息 | conversations / messages |
业务主数据(会话日志格式规范) | 坐席 / 管理员 | 已实现 |
关系图:配置变更动作同时写 A 与 B(双写,不收敛);C 记录自动化对外调用;D 是应用层运行日志;E 是业务数据,阶段四对其约定「会话日志格式规范」。
flowchart LR
subgraph 写
PUT[PUT /api/admin/configs/key] -->|双写| A[(A config_change_logs)]
PUT -->|双写 config_change 事件| B[(B audit_logs)]
end
subgraph 落表
AUTO[自动化动作] --> C[(C auto_action_logs)]
APP[应用运行] -->|JSONFormatter + trace_id| D[(D stdout→Docker文件)]
CHAT[会话/消息] --> E[(E conversations/messages)]
end
subgraph 读-管理后台
A --> PA[配置变更历史页]
B --> PB[安全审计日志页]
C -. 暂未暴露列表接口 .-> PC[(待定)]
D --> PD[运行期日志查看页]
E --> PE[会话管理]
end
3. 逐类详述
3.1 A — 配置变更历史(系统日志)
定义:系统配置项被修改时自动记录的前后值差异(diff),用于「配置改了什么、谁改的、什么时候改的」可回溯。
使用场景(谁 / 何时 / 为什么):
- 谁:系统管理员(admin)。
- 何时:调用
PUT /api/admin/configs/{key}更新任意配置项时,由后端自动写入(该接口注释「更新单个配置项(同时记录变更日志)」)。 - 为什么:排查「为什么某功能表现变了」时,快速定位配置被谁在何时改成什么值。
接口:
| 项目 | 说明 |
|---|---|
| 列表查询 | GET /api/admin/system-logs(当前参数 page / page_size) |
| 写入触发 | PUT /api/admin/configs/{key}(admin_api.py 第 117 行)→ 同时写 A 与 B |
| 实现 | admin_service.get_system_logs |
| 权限 | admin(沿用 /api/admin 鉴权;建议明确为 config_log:read) |
决策 3(待开发):
GET /api/admin/system-logs需补充过滤参数config_key(配置键)、changed_by(操作人 agent_id)、changed_from/changed_to(时间),并在前端 A 页面增加对应筛选控件。
数据模型(JSON Schema 风格):
{
"ConfigChangeLog": {
"config_key": "string // 配置项键",
"old_value": "string? // 变更前的值",
"new_value": "string? // 变更后的值",
"changed_by": "string // 操作人 agent_id",
"changed_by_name": "string // 操作人姓名",
"changed_at": "datetime // 变更时间"
}
}
Schema:
backend/app/schemas/admin.py的ConfigHistoryItem;模型:backend/app/models/config_change_log.py。前端:frontend-admin/src/views/SystemLogs.vue(el-table 五列:时间 / 配置键 / 操作人 / 变更前红色删除线 / 变更后绿色 + 分页 20/50/100)。
UI 命名(决策 1):管理后台侧边栏原「系统日志」→ 明确命名为 「配置变更历史」,与 B 的「安全审计日志」并列区分。
3.2 B — 安全审计日志(操作日志 / 审计日志)
定义:记录系统中与安全相关的行为事件(登录、消息、会话、管理员操作、配置变更等),用于审计与合规追溯。
使用场景(谁 / 何时 / 为什么):
- 谁:管理员、审计员(auditor)。
- 何时:关键行为发生时由对应业务代码写入(见下方「已记录事件」)。
- 为什么:安全审计、责任追溯、异常行为发现(如异常登录、敏感数据查询)。
接口:
| 项目 | 说明 |
|---|---|
| 查询 | GET /admin/audit-logs(router 前缀 /admin/audit-logs) |
| 过滤参数 | employee_id / action / resource / from / to / page / page_size |
| 权限 | audit_log:read:all(admin / auditor 角色) |
| 实现 | backend/app/api/audit_logs.py |
数据模型(JSON Schema 风格):
{
"AuditLog": {
"employee_id": "string // 操作人",
"action": "string // 动作类型,如 login/logout/config_change",
"resource": "string // 资源类型",
"resource_id": "string? // 资源标识",
"details": "object // JSON:前后值 / IP / UA 等",
"result": "enum(success|failure|partial)",
"ip_address": "string // 来源 IP",
"user_agent": "string // UA",
"created_at": "datetime // 发生时间"
}
}
已记录事件(安全审计报告 §3):登录 / 登出、消息发送、会话创建关闭、管理员操作、配置变更。 待补事件:敏感数据查询(P1)、角色变更(P1)、系统配置变更(P1)、异常登录(P1)、API 调用统计(P2)。
UI 命名(决策 1):管理后台侧边栏明确命名为 「安全审计日志」,与 A 的「配置变更历史」区分。
3.3 C — 自动化动作日志
定义:自动化流程调用外部系统时的出入参全量落表,用于排障与审计。
使用场景(谁 / 何时 / 为什么):
- 谁:运维 / 开发(排障);审计(追溯外部调用)。
- 何时:自动化动作触发外部系统调用(如
huorong.isolate火绒隔离)时。 - 为什么:外部调用失败 / 耗时异常时,定位是请求问题还是对方系统问题。
接口 / 落点:
| 项目 | 说明 |
|---|---|
| 落点 | auto_action_logs(模型 ActionLog,backend/app/models/automation.py 第 249 行) |
| 管理后台列表接口 | 暂未暴露(当前仅落表);如需可视化查询可后续补充 |
数据模型(JSON Schema 风格):
{
"ActionLog": {
"session_id": "string? // 关联会话",
"action_id": "string? // 自动化动作 ID",
"employee_id": "string? // 触发员工",
"event": "string // 事件,如 huorong.isolate",
"direction": "enum(in|out) // 入/出方向",
"system": "string // 外部系统",
"request": "object // 请求(脱敏)",
"response": "object // 响应(脱敏)",
"status": "string // 状态",
"latency_ms": "int? // 耗时",
"error": "string? // 错误信息"
}
}
3.4 D — 运行期结构化日志
定义:应用运行期输出的结构化日志(JSON),承载排障信息,含 request_id / user_id 上下文。
落点与现状(日志结构化审计报告 §3):
- 落点:stdout → Docker 文件;
JSONFormatter+ 中间件注入trace_id(辅助函数log_business/log_security)。 - 短期:stdout +
docker logs+grep(Docker 收集到/var/log/wecom-it-desk/*.log)。 - 中长远:Loki + Promtail(中期)/ ELK(长期)。
管理后台「日志查看」:管理员手册 §10.2 承诺「按时间、级别筛选日志,支持下载日志文件」,已落地:前端 RuntimeLogs.vue(4 项筛选 + 下载按钮)+ 后端 GET /api/admin/runtime-logs(download=true 流式返回)+ 部署 docker-compose.yml 挂载 RUNTIME_LOG_DIR=/app/logs(详见 sysdesign.md 第六节)。
D 页面产品规格(决策 4,详见 §5.1):筛选维度 = 级别 + 时间;下载格式 = .txt / .log;权限 = admin。
3.5 E — 会话 / 消息记录
定义:业务主数据(非独立日志子系统),记录员工与坐席的会话及消息。
落点:conversations / messages 表。
与日志的关系:PRD 阶段四「会话日志格式规范」是对其记录格式的约定,为后续审计与分析打基础(属于 B 审计的数据来源之一,也支撑阶段四的数据统计看板)。
4. 关键辨析:A(记配置值 diff) vs B(记安全行为事件)
| 维度 | A 配置变更历史 | B 安全审计日志 |
|---|---|---|
| 记录对象 | 配置项值 diff(old_value → new_value) | 安全行为事件(action + resource + result) |
| 触发点 | PUT /api/admin/configs/{key} |
登录/登出/消息/会话/管理员操作/配置变更等 |
| 字段重心 | config_key / old_value / new_value / changed_by / changed_at |
action / resource / result / ip_address / user_agent / details |
| 核心问题 | 「配置被改成什么了?」 | 「谁做了什么安全动作?结果如何?」 |
| 主要读者 | 管理员(查配置变更) | 管理员 / 审计员(审计追溯) |
| 列表接口 | GET /api/admin/system-logs(参数待补) |
GET /admin/audit-logs(多过滤参数) |
| 权限 | admin | audit_log:read:all(admin / auditor) |
| 双写关系 | 同一配置变更动作同时写 A 与 B(config_change 事件) |
同上 |
结论:A 与 B 是「同一动作的两个视角」——A 记「值」,B 记「事」。决策 2 明确维持双写、不收敛。
5. 5 项决策的产品化表述 + 验收标准
决策来源:用户(宋献)2026-07-09 拍板。本文档严格承袭,未自行增减范围。
| # | 决策 | 优先级 | 产品化表述 | 验收标准 |
|---|---|---|---|---|
| 1 | 命名与归并 | P1 | 管理后台侧边栏「系统日志」明确区分命名:配置变更历史(A) vs 安全审计日志(B) | ① 侧边栏出现两个独立、命名清晰的入口;② 入口标题与本文档 A/B 命名一致,无「系统日志」歧义统称 |
| 2 | 双写边界 | P0 | 配置变更维持 A+B 双写,不收敛 | ① PUT /api/admin/configs/{key} 同时写 config_change_logs 与 audit_logs 的 config_change 事件;② 不在任一侧删除或合并 |
| 3 | 筛选能力 | P1 | A 页面补充「配置键 / 操作人 / 时间」筛选 | ① 前端 A 页增加三类筛选控件;② 后端 GET /api/admin/system-logs 支持 config_key / changed_by / changed_from~changed_to 过滤参数;③ 筛选结果与分页正确联动 |
| 4 | 运行期日志查看 | P0 | 落地 D「按级别 / 时间筛选 + 下载」页面与后端接口 | 见 §5.1 D 页面产品规格表,全部满足 |
| 5 | 文档闭环 | — | 补《系统日志/审计日志 产品+设计文档》,并入 PRD v1.2 与架构 v1.3,列入项目任务 | ① 本文档已建立;② PRD / 架构已增补日志体系小节;③ 状态看板登记 #101–#104 |
5.1 决策 4 — D 运行期日志查看页 产品规格
| 规格项 | 定义 |
|---|---|
| 页面名称 | 运行期日志查看(管理后台侧边栏入口) |
| 权限 | admin(仅管理员可访问) |
| 数据来源 | 后端聚合 RUNTIME_LOG_DIR(容器内 /app/logs)下 *.log(JSONFormatter 逐行 JSON 输出)。落地方案:应用层 RotatingFileHandler 写入 + docker-compose 宿主机目录 bind mount(/var/log/wecom-it-desk:/app/logs);stdout 仍由 docker json-file 捕获供 docker logs 兜底。中长远 = Loki / ELK |
| 筛选维度 | 级别(DEBUG / INFO / WARNING / ERROR / CRITICAL)+ 时间(from / to) |
| 关键字检索 | 支持按文本关键字检索(如 trace_id / 员工 ID) |
| 下载 | 支持下载筛选后的日志,格式 .txt / .log |
| 分页 / 加载 | 支持分页(默认 100/页,可切 20/50/100) |
| 后端接口(已落地) | GET /api/admin/runtime-logs(参数:level / from / to / keyword / page / page_size / download,download=true 时以 text/plain 流式返回命中行,文件名 runtime-logs-{ts}.log) |
| 验收标准 | ① admin 可筛选级别 + 时间查看日志;② 可下载 .txt / .log;③ 非 admin 无权限;④ 非 admin 调用接口返回 403 |
6. 待确认 / 遗留问题
- D 页后端聚合实现方案:短期已定稿(应用层 JSON 文件日志 + docker-compose 宿主机目录 bind mount,详见 sysdesign.md 第六节),中长期 是否切换 Loki / ELK 仍待架构师(高见远)按数据量与检索需求评估后决策。
- B 待补事件排期:敏感数据查询 / 角色变更 / 系统配置变更 / 异常登录(P1),API 调用统计(P2)——需纳入迭代计划。
- C 是否需管理后台可视化查询接口:当前仅落表,无列表页;若审计 / 排障需要,后续补充
GET /admin/auto-action-logs(权限待定)。 - A 页面权限命名:建议明确为
config_log:read(当前沿用/api/admin鉴权);可与 B 的audit_log:read:all一并纳入 RBAC 梳理。 - E 与 B 的衔接:阶段四「会话日志格式规范」落地后,需确保会话相关行为在 B 中有对应审计事件。
变更记录
| 版本 | 日期 | 变更说明 |
|---|---|---|
| v1.0 | 2026-07-09 | 初稿(许清楚) |
| v1.2.1 | 2026-08-04 | §5.1 D 接口与「待开发」措辞修正为已落地状态;下载接口统一为 query 参数 download=true(不再使用 /runtime-logs/download 子路径);§6 D 页后端聚合实现方案标注短期已定稿(应用层 JSON 文件 + bind mount) |