Files
logs/doc/日志监控.md
2026-04-27 19:26:57 +08:00

499 lines
15 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Ops Logs 前端页面设计文档Log Mgmt
## 1. 背景与目标
`Logs` 服务负责采集并归一化设备侧日志Syslog / SNMP Trap并提供规则与字典等配置能力。前端需要在统一的后台界面中完成
1. 日志查询(查看归一化后的日志事件及详情)
2. Syslog 规则配置
3. Trap 规则配置
4. Trap 字典配置
5. Trap 屏蔽/抑制规则配置
本设计以当前代码库的后端模型与前端实现为准:后端路由在 `internal/routers/register.go`,前端页面在 `front/src/views/ops/pages/log-mgmt/**/index.vue`
---
## 2. 范围(页面数量与路由)
本模块共 5 个页面,对应后端 5 组资源(列表+CRUD 或列表+详情抽屉)。
| 页面 | 菜单/路由路径 | 前端组件 |
|---|---|---|
| 日志查询 | `/log-mgmt/entries` | `front/src/views/ops/pages/log-mgmt/entries/index.vue` |
| Syslog 匹配规则 | `/log-mgmt/syslog-rules` | `front/src/views/ops/pages/log-mgmt/syslog-rules/index.vue` |
| SNMP Trap 匹配规则 | `/log-mgmt/trap-rules` | `front/src/views/ops/pages/log-mgmt/trap-rules/index.vue` |
| Trap 字典 | `/log-mgmt/trap-dictionary` | `front/src/views/ops/pages/log-mgmt/trap-dictionary/index.vue` |
| Trap 屏蔽/抑制 | `/log-mgmt/trap-suppressions` | `front/src/views/ops/pages/log-mgmt/trap-suppressions/index.vue` |
路由与菜单配置参考:
- `front/src/router/local-menu-flat.ts` / `front/src/router/local-menu-items.ts`
- `front/src/views/ops/pages/system-settings/system-logs/index.vue`(页面入口按钮)
- `front/src/views/ops/pages/monitor/log/index.vue`(嵌入 `LogMgmtEntries`
---
## 3. 数据对象与接口映射
后端认证API 路由组启用 `middleware.JwtAuth(true)`
前端请求的 API Base`front/src/api/ops/logs.ts` 中为 `/Logs/v1`
### 3.1 日志事件entries
- 接口:`GET /Logs/v1/entries`
- 返回结构(前端类型):`LogEntriesResult``total``page``page_size``items`
- 日志事件字段(前端类型 `LogEvent`
- `id`
- `created_at`
- `source_kind``syslog` / `snmp_trap`
- `remote_addr`
- `raw_payload`
- `normalized_summary`
- `normalized_detail`
- `device_name`
- `severity_code`
- `trap_oid`
- `alert_sent`
后端实现:`internal/models/log_event.go``internal/logic/controllers/crud.go``ListLogEvents`)。
### 3.2 Syslog 规则syslog-rules
- 接口:
- `GET /Logs/v1/syslog-rules`
- `POST /Logs/v1/syslog-rules`
- `PUT /Logs/v1/syslog-rules/:id`
- `DELETE /Logs/v1/syslog-rules/:id`
- 规则字段(前端类型 `SyslogRule` / 后端 `SyslogRule`
- `id``created_at``updated_at`
- `name`
- `enabled`
- `priority`
- `device_name_contains`
- `keyword_regex`
- `alert_name`
- `severity_code`
- `policy_id`
后端实现:`internal/models/syslog_rule.go``internal/logic/controllers/crud.go`
### 3.3 Trap 规则trap-rules
- 接口:
- `GET /Logs/v1/trap-rules`
- `POST /Logs/v1/trap-rules`
- `PUT /Logs/v1/trap-rules/:id`
- `DELETE /Logs/v1/trap-rules/:id`
- 规则字段(前端类型 `TrapRule` / 后端 `TrapRule`
- `name`
- `enabled`
- `priority`
- `oid_prefix`
- `varbind_match_regex`
- `alert_name`
- `severity_code`
- `policy_id`
后端实现:`internal/models/trap_rule.go``internal/logic/controllers/crud.go`
### 3.4 Trap 字典trap-dictionary
- 接口:
- `GET /Logs/v1/trap-dictionary`
- `POST /Logs/v1/trap-dictionary`
- `PUT /Logs/v1/trap-dictionary/:id`
- `DELETE /Logs/v1/trap-dictionary/:id`
- 字典条目字段(前端类型 `TrapDictionaryEntry` / 后端 `TrapDictionaryEntry`
- `oid_prefix`后端约束uniqueIndex
- `title`
- `description`
- `severity_code`
- `recovery_message`
- `enabled`
后端实现:`internal/models/trap_dictionary.go``internal/logic/controllers/crud.go`
### 3.5 Trap 屏蔽/抑制trap-suppressions
- 接口:
- `GET /Logs/v1/trap-suppressions`
- `POST /Logs/v1/trap-suppressions`
- `PUT /Logs/v1/trap-suppressions/:id`
- `DELETE /Logs/v1/trap-suppressions/:id`
- 屏蔽规则字段(前端类型 `TrapShield` / 后端 `TrapShield`
- `name`
- `enabled`
- `source_ip_cidr`
- `oid_prefix`
- `interface_hint`
- `time_windows_json`JSON 字符串)
后端实现:`internal/models/trap_shield.go``internal/logic/controllers/crud.go`
---
## 4. 页面设计详情(逐页)
### 4.1 日志查询页(`/log-mgmt/entries`
目标:以“可筛选的列表 + 详情抽屉”方式查看归一化日志事件。
#### 1顶部筛选区
- 使用 `search-table` 组件
- 筛选项:`source_kind`(下拉)
- `全部`value=''
- `Syslog`value='syslog'
- `SNMP Trap`value='snmp_trap'
筛选触发:`@search` 调用 `handleSearch`,重置则 `@reset` 调用 `handleReset`
#### 2列表表格列Columns
表格由 `columns` 定义,主要列:
- `ID`
- `来源``source_kind`,通过 `sourceKindLabel()` 显示(`syslog`->`Syslog``snmp_trap`->`SNMP Trap`
- `时间``created_at`
- `来源地址``remote_addr`
- `设备``device_name`
- `级别``severity_code`
- `OID``trap_oid`
- `原始报文``raw_payload`
- 使用 slot `raw_payload`:省略显示,保留 `tooltip`
- `已告警``alert_sent`
- 使用 slot `alert_sent``a-tag`(已转发/否)
- `操作`slot `operations`
- `详情`:打开右侧抽屉
#### 3详情抽屉a-drawer
- 打开逻辑:点击表格行操作中的 `详情`,调用 `openDetail(record)`
- 抽屉展示:`a-descriptions`1 列bordered
- 展示字段:
- 来源类型(`source_kind`
- 采集时间(`created_at`
- 来源地址(`remote_addr`,空则 `-`
- 设备名(`device_name`
- 严重级别(`severity_code`
- Trap OID`trap_oid`
- 已转发告警(`alert_sent`
- 摘要(`normalized_summary`
- 详情(`normalized_detail``pre-block` 预格式化展示)
- 原始报文(`raw_payload``pre-block` 预格式化展示)
#### 4分页策略
- 分页参数由前端 `pagination.current/pageSize` 控制,并随筛选条件一起请求后端:
- 调用 `fetchLogEntries({ page, page_size, source_kind })`
### 4.2 Syslog 规则页(`/log-mgmt/syslog-rules`
目标:规则的“列表 + 新建/编辑弹窗 + 删除确认”。
#### 1通用列表与本地过滤
- 使用 `search-table`,并在前端进行“关键词本地过滤”,过滤字段:
- `name`
- `alert_name`
- `keyword_regex`
- 搜索输入字段:
- `keyword`label`关键词`placeholder`规则名 / 告警名`
说明:该页(以及 trap-*、dictionary、suppressions 三类列表页)采用“先拉取全量 -> 本地过滤 -> 切片分页”的方式。
#### 2表格列
- `ID`
- `名称``name`
- `优先级``priority`
- `启用``enabled`slot `enabled`tag启用/禁用)
- `设备名包含``device_name_contains`
- `关键字正则``keyword_regex`
- `告警名``alert_name`
- `级别``severity_code`
- `策略ID``policy_id`
- `操作`:编辑/删除
#### 3新建/编辑弹窗a-modal
- 弹窗标题:
- 新建:`新建 Syslog 规则`
- 编辑:`编辑规则 #${editingId}`
- 表单 `a-form`(布局 `vertical`
- 表单字段:
- `name``a-input`(必填)
- `enabled``a-switch`
- `priority``a-input-number`
- `device_name_contains``a-input`
- `keyword_regex``a-input`
- `alert_name``a-input`
- `severity_code``a-input`
- `policy_id``a-input-number`min=0
提交逻辑:
- 编辑:`updateSyslogRule(editingId, { ...formData })`
- 新建:`createSyslogRule({ ...formData })`
- 成功后关闭弹窗并刷新列表 `fetchList()`
#### 4删除确认
- `Modal.confirm` 二次确认
- 删除接口:`deleteSyslogRule(id)`
### 4.3 Trap 规则页(`/log-mgmt/trap-rules`
目标TrapRule 的列表+弹窗 CRUD与 Syslog 规则页同构。
#### 1本地过滤关键词
- 字段:`keyword`
- 匹配来源:
- `name`
- `oid_prefix`
- `alert_name`
#### 2表格列
- `ID``名称``优先级``启用`
- `OID 前缀``oid_prefix`
- `Varbind 正则``varbind_match_regex`
- `告警名``alert_name`
- `级别``severity_code`
- `策略ID``policy_id`
- 操作:编辑/删除
#### 3弹窗表单字段
- `name`(必填)
- `enabled`
- `priority`
- `oid_prefix`
- `varbind_match_regex`
- `alert_name`
- `severity_code`
- `policy_id`min=0
### 4.4 Trap 字典页(`/log-mgmt/trap-dictionary`
目标TrapDictionaryEntry 的列表+弹窗 CRUD。
#### 1本地过滤关键词
- 匹配字段:
- `oid_prefix`
- `title`
- `description`
#### 2表格列
- `ID`
- `OID 前缀``oid_prefix`
- `标题``title`
- `级别``severity_code`
- `启用``enabled`
- `描述``description`
- 操作:编辑/删除
#### 3弹窗表单字段
- `oid_prefix`(必填,建议提示“唯一前缀”)
- `title`(必填)
- `description``a-textarea`rows=3
- `severity_code`
- `enabled`
- `recovery_message``a-textarea`rows=2
### 4.5 Trap 屏蔽/抑制页(`/log-mgmt/trap-suppressions`
目标TrapShield 的列表+弹窗 CRUD并对 `time_windows_json` 做前端校验。
#### 1本地过滤关键词
- 匹配字段:
- `name`
- `oid_prefix`
- `source_ip_cidr`
#### 2表格列
- `ID`
- `名称``name`
- `启用``enabled`
- `源 IP/CIDR``source_ip_cidr`
- `OID 前缀``oid_prefix`
- `接口提示``interface_hint`
- 操作:编辑/删除
#### 3弹窗表单字段
- `name`(必填)
- `enabled`
- `source_ip_cidr`
- `oid_prefix`
- `interface_hint`
- `time_windows_json``a-textarea`rows=4placeholder=`{}`
#### 4time_windows_json JSON 校验
-`time_windows_json` 非空时:
-`trim` 后尝试 `JSON.parse(tw)`
- 校验失败:`Message.warning('时间窗 JSON 格式无效')` 并阻止提交
---
## 5. 页面交互一致性要求(实现要点)
为了保证各列表页体验一致,本模块约定:
1. 列表页使用统一的 `search-table` 布局(顶部搜索、表格、分页、刷新)
2. 规则类/字典/屏蔽页采用“拉取全量 -> 本地过滤 -> 切片分页”的方式
3. 创建/编辑统一使用 `a-modal`,提交按钮触发 `formRef.validate()`
4. 删除统一使用 `Modal.confirm`,成功后刷新列表并给出 `Message.success`
5. `trap-suppressions``time_windows_json` 进行 JSON 字符串合法性校验
---
## 6. 数据流(简图)
```mermaid
flowchart LR
UI[前端页面search-table + 表格/弹窗/抽屉)] --> API[front/src/api/ops/logs.ts]
API --> BE[后端路由 internal/routers/register.go]
BE --> DB[(Postgres)]
BE --> Refresh[ingest.Global.Refresh()(规则/字典/屏蔽变更后触发)]
```
---
## 7. 中优先级待办(已立项,未完成)
本节用于记录当前版本可用但尚未产品化完善的中优先级项,作为后续迭代输入。
### 7.1 Outbox 可观测性增强
当前状态:
- 已支持 `alert_outbox` 入队、重试、死信、手动重试;
- 已有基础列表查询接口和前端入口。
待完善内容:
- 增加 outbox 指标接口或埋点:
- `pending_count`
- `retrying_count`
- `dead_count`
- `dispatch_success_rate`
- `dispatch_latency_p95`
- 增加失败原因聚合视图(按 `last_error` 分类统计)。
- 增加任务生命周期字段(首次入队时间、最后发送时间)用于问题排查。
建议落地文件:
- 后端:`internal/logic/controllers/outbox.go``internal/ingest/alert_outbox.go`
- 前端:`front/src/views/ops/pages/log-mgmt/entries/index.vue`
### 7.2 分发状态模型统一(替代 bool
当前状态:
- `logs_events` 已新增 `dispatch_status`,并在 outbox 流程中维护状态。
- 历史字段 `alert_sent` 仍保留,用于兼容旧页面展示。
待完善内容:
- 明确状态枚举为:`not_applicable/pending/retrying/sent/dead`
- 前后端统一以 `dispatch_status` 作为主状态字段,`alert_sent` 逐步降级为派生字段或移除。
- 页面文案由“已告警”升级为“分发状态”主展示,避免语义歧义。
建议落地文件:
- 后端:`internal/models/log_event.go``internal/logic/controllers/crud.go`
- 前端:`front/src/api/ops/logs.ts``front/src/views/ops/pages/log-mgmt/entries/index.vue`
### 7.3 关键路径测试补齐
当前状态:
- 已有基础单测覆盖核心函数。
待完善内容:
- 增加资源事件安全链路测试:
- 验签失败/成功
- 超时事件拒绝
- 幂等事件重复提交
- 增加 outbox 重试链路测试:
- 发送成功更新状态
- 重试次数递增
- 超过阈值转 `dead`
- 增加资源冲突优先级测试:
- `server > collector > device`
建议落地文件:
- `internal/logic/controllers/resource_event_test.go`
- `internal/ingest/alert_outbox_test.go`
- `internal/ingest/resource_resolver_test.go`
---
## 8. 后续产品化规划Phase 3
本节对应“可运维与产品化”阶段,优先级低于中优先级修复项,但会显著提升系统可管理性。
### 8.1 规则发布流draft / publish / rollback
目标:
- 规则配置与生效状态解耦,降低误操作风险。
范围:
- 引入规则草稿态与发布态;
- 支持发布记录、回滚到历史版本;
- 变更需记录操作人、时间、变更说明。
接口建议:
- `POST /Logs/v1/rule-sets/:id/publish`
- `POST /Logs/v1/rule-sets/:id/rollback`
- `GET /Logs/v1/rule-sets/:id/history`
### 8.2 规则仿真/回放能力
目标:
- 上线前可验证规则命中结果,减少误报漏报。
范围:
- 输入样本报文syslog/trap执行仿真
- 返回命中链路(命中/未命中原因);
- 支持历史事件回放。
接口建议:
- `POST /Logs/v1/rule-sets/:id/simulate`
- `POST /Logs/v1/rule-sets/:id/replay`
### 8.3 指标与审计面板
目标:
- 建立“采集-匹配-分发”全链路可观测性。
范围:
- 采集侧:接收速率、解析失败率;
- 匹配侧:命中率、规则耗时;
- 分发侧:成功率、重试率、死信量;
- 安全侧:验签失败次数、重放拦截次数。
前端建议:
- 在日志管理模块增加“运行指标”页签;
- 对死信和验签失败提供快捷定位入口。
---
## 9. 未完成项执行顺序(建议)
为降低风险,建议按以下顺序推进:
1. **中优先级先完成**
- outbox 指标与失败聚合
- `dispatch_status` 主状态化
- 关键路径测试补齐
2. **再做产品化**
- 规则发布流
- 规则仿真/回放
- 指标与审计面板
验收建议:
- 每项功能完成后执行“单项验证 + 回归验证”,最后统一做端到端联调。