Files
waf-platform/日志策略逻辑梳理与问题清单.md
2026-02-10 23:43:05 +08:00

149 lines
7.4 KiB
Markdown
Raw 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.

# 日志策略逻辑梳理与问题清单(当前基线:`E:\AI_PRODUCT\waf-platform`
## 1. 结论摘要
- 当前链路是 **`type` + `writeTargets` 双字段共同决定行为**。
- 运行时真正用于读写判断的是 `writeTargets``ParseWriteTargetsFromPolicy` 解析结果)。
- HTTP 与 DNS 都已接入“公用策略”下发DNS 也已支持 ClickHouse 读取。
- 目前存在多处逻辑不一致,核心风险是:**页面显示、数据库值、实际读写行为可能不同步**。
## 2. 关键入口文件
- 类型与组合映射:`EdgeCommon/pkg/serverconfigs/access_log_storages.go`
- 写入目标定义/解析:`EdgeCommon/pkg/serverconfigs/access_log_write_targets.go`
- 策略创建/更新Admin`EdgeAdmin/internal/web/actions/default/servers/accesslogs/createPopup.go``EdgeAdmin/internal/web/actions/default/servers/accesslogs/update.go`
- 策略保存API`EdgeAPI/internal/rpc/services/service_http_access_log_policy_plus.go`
- 策略落库DAO`EdgeAPI/internal/db/models/http_access_log_policy_dao.go`
- 公用策略运行时缓存:`EdgeAPI/internal/accesslogs/storage_manager.go`
- HTTP 节点队列:`EdgeNode/internal/nodes/http_access_log_queue.go`
- DNS 节点队列:`EdgeDNS/internal/nodes/ns_access_log_queue.go`
- 节点配置下发:`EdgeAPI/internal/db/models/node_dao.go``EdgeAPI/internal/db/models/ns_node_dao_plus.go`
- HTTP 查询服务:`EdgeAPI/internal/rpc/services/service_http_access_log.go`
- DNS 查询服务:`EdgeAPI/internal/rpc/services/nameservers/service_ns_access_log.go`
- CH 查询实现:`EdgeAPI/internal/clickhouse/logs_ingest_store.go``EdgeAPI/internal/clickhouse/ns_logs_ingest_store.go`
## 3. 数据模型与语义
`edgeHTTPAccessLogPolicies` 关键字段:
- `type``file` / `file_mysql` / `file_clickhouse` / `file_mysql_clickhouse` / `es` / `tcp` / `syslog` / `command`
- `writeTargets`JSON`file/mysql/clickhouse` 三个布尔值)
- `disableDefaultDB`:停用默认数据库存储(兼容旧语义)
当前实际规则:
1. Admin 侧根据下拉 `type` 生成 `writeTargetsJSON`
2. API 原样落库(仅做少量历史 type 别名兼容)。
3. 运行时使用 `ParseWriteTargetsFromPolicy(writeTargets, type, disableDefaultDB)` 得到最终写入目标。
## 4. 端到端链路(当前行为)
### 4.1 策略创建/更新
- 创建与更新都会调用 `ParseStorageTypeAndWriteTargets`,并同时提交 `type``writeTargetsJSON`
- `file_clickhouse` / `file_mysql_clickhouse` 在 UI 上隐藏了手填路径输入,依赖旧值或默认目录回退。
- DAO 更新时,只有 `writeTargetsJSON` 非空才会覆盖 `writeTargets` 字段。
### 4.2 HTTP 写入链路
- Node 侧:
- `needWriteFile = writeTargets == nil || writeTargets.NeedWriteFile()`
- `needReportAPI = writeTargets == nil || writeTargets.NeedReportToAPI()`
- API 侧:
- `CreateHTTPAccessLogs` 里是否写 MySQL 由 `canWriteAccessLogsToDB() -> WriteMySQL()` 决定。
- 同时调用 `writeAccessLogsToPolicy()`,把日志再交给公用策略存储引擎处理(如 file/es/tcp/syslog/command
- 查询侧:
- `shouldReadAccessLogsFromClickHouse()` 为真且 CH 配置可用时优先读 CH。
- CH 失败后,按 `shouldReadAccessLogsFromMySQL()` 回退 MySQL。
### 4.3 DNS 写入链路
- DNS 节点:
- `needWriteFile = targets == nil || targets.File || targets.ClickHouse`
- `needReportAPI = targets == nil || targets.MySQL`
- 即 CH-only 下 DNS 只写本地文件,不上报 API。
- DNS API 查询:
- 与 HTTP 一样优先 CH再按策略回退 MySQL。
### 4.4 节点路径更新机制
- API 下发公用策略的 `AccessLogFilePath``AccessLogWriteTargets` 到 HTTP/DNS 节点配置。
- Node/DNS 收到新配置后会 `SetDirByPolicyPath(...)``EnsureInit/Reopen/Close`,可自动切换目录。
- 空路径时会回退到:
- HTTP`EDGE_LOG_DIR` 或默认 `/var/log/edge/edge-node`
- DNS`EDGE_DNS_LOG_DIR` 或默认 `/var/log/edge/edge-dns`
## 5. 行为矩阵(按当前代码)
- `file`
- 写文件:是
- 写 MySQL仅当 `writeTargets.mysql=true` 才会写)
- 读:优先 CH若开启否则按 MySQL 开关
- `file_mysql`
- 写文件:是
- 写 MySQL
-MySQL 可读;若 CH 也开则优先 CH
- `file_clickhouse`
- 写文件:是
- 写 MySQL理论上
- 读:优先 CH若 CH 不可用且 mysql=false则返回空
- `file_mysql_clickhouse`
- 写文件:是
- 写 MySQL
- 读:优先 CH失败回退 MySQL
- `es/tcp/syslog/command`
- 仍会由 `writeTargets` 决定是否 MySQL当前解析默认给 MySQL=true
- 另外会通过策略引擎输出到对应目标
## 6. 逻辑问题清单(按优先级)
### P0`type` 与 `writeTargets` 双真源,容易漂移
- 页面展示与回显会参考 `type`,实际写读判断优先看 `writeTargets`
- 一旦两者不一致会出现“UI 看起来是 ClickHouse实际还在写/读 MySQL”。
### P0`disableDefaultDB` 在新链路中容易失效
- `WriteMySQL()` 优先看 `writeTargets.MySQL`,只有 `writeTargets` 为空才回退 `disableDefaultDB`
- 由于 Admin 基本总会提交 `writeTargetsJSON``disableDefaultDB` 常常不会真正生效。
### P1HTTP 与 DNS 在 CH-only 场景上报 API 语义不一致
- HTTP`NeedReportToAPI()` = `MySQL || ClickHouse`CH-only 仍会上报 API。
- DNSCH-only 不上报 API仅写文件给 Fluent Bit。
- 高并发下会带来不必要的 API 压力与行为差异。
### P1`file_clickhouse` 可能出现空路径,策略引擎会启动失败
- `FileStorage.Start()` 要求 `path` 非空。
- 但 UI 在 clickhouse 组合类型隐藏路径输入,若 `options.path` 为空,策略引擎会报错(虽然节点本地写文件仍可回退目录工作)。
### P1HTTP 可能出现“节点写文件 + API 再写文件”的重复路径
- `CreateHTTPAccessLogs` 无论是否写 MySQL都会 `writeAccessLogsToPolicy()`
- 公用策略若为 file*API 侧 `StorageManager.createStorage()` 会创建 `FileStorage` 并再次落文件。
- 若目标是“仅节点写文件供 Fluent Bit 采集”,这会引入额外重复写入。
### P2DNS `requestId` 生成算法有重复风险
- `ns_access_log_queue.go``timestamp/requestId``loop()` 局部变量,每轮 tick 重置。
- 同秒跨批次可能冲突,影响游标分页与去重。
### P2UI 文案分支存在不可达条件
- `createPopup.html` / `update.html``file|file_mysql` 区块内嵌了 clickhouse 条件文案分支,实际不会触发。
- 不影响功能,但会增加理解成本。
## 7. 建议修复顺序
1. 先统一单一真源(建议 API 层统一按 `type` 规范化并覆盖 `writeTargets`)。
2. 明确 `disableDefaultDB``writeTargets` 的优先级,避免“配置项在 UI 可选但不生效”。
3. 统一 HTTP/DNS 在 CH-only 的上报语义(建议都走“节点文件 + Fluent Bit”API 不再接收该流量)。
4. 修复 file_clickhouse 空路径策略启动失败(要求路径 or 统一默认路径回填到 options
5. 修复 DNS requestId 生成(全局原子递增或更高精度时间戳方案)。
## 8. 当前可用性判断
- 系统“可运行”,但配置行为存在歧义,且在高并发下会放大成本和排障难度。
- 若目标是稳定的高吞吐日志链路,建议优先处理 P0/P1 问题后再继续线上放量。