7.4 KiB
7.4 KiB
日志策略逻辑梳理与问题清单(当前基线: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/commandwriteTargets:JSON(file/mysql/clickhouse三个布尔值)disableDefaultDB:停用默认数据库存储(兼容旧语义)
当前实际规则:
- Admin 侧根据下拉
type生成writeTargetsJSON。 - API 原样落库(仅做少量历史 type 别名兼容)。
- 运行时使用
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.ClickHouseneedReportAPI = 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
- HTTP:
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常常不会真正生效。
P1:HTTP 与 DNS 在 CH-only 场景上报 API 语义不一致
- HTTP:
NeedReportToAPI()=MySQL || ClickHouse,CH-only 仍会上报 API。 - DNS:CH-only 不上报 API,仅写文件给 Fluent Bit。
- 高并发下会带来不必要的 API 压力与行为差异。
P1:file_clickhouse 可能出现空路径,策略引擎会启动失败
FileStorage.Start()要求path非空。- 但 UI 在 clickhouse 组合类型隐藏路径输入,若
options.path为空,策略引擎会报错(虽然节点本地写文件仍可回退目录工作)。
P1:HTTP 可能出现“节点写文件 + API 再写文件”的重复路径
CreateHTTPAccessLogs无论是否写 MySQL,都会writeAccessLogsToPolicy()。- 公用策略若为 file*,API 侧
StorageManager.createStorage()会创建FileStorage并再次落文件。 - 若目标是“仅节点写文件供 Fluent Bit 采集”,这会引入额外重复写入。
P2:DNS requestId 生成算法有重复风险
ns_access_log_queue.go里timestamp/requestId为loop()局部变量,每轮 tick 重置。- 同秒跨批次可能冲突,影响游标分页与去重。
P2:UI 文案分支存在不可达条件
createPopup.html/update.html在file|file_mysql区块内嵌了 clickhouse 条件文案分支,实际不会触发。- 不影响功能,但会增加理解成本。
7. 建议修复顺序
- 先统一单一真源(建议 API 层统一按
type规范化并覆盖writeTargets)。 - 明确
disableDefaultDB与writeTargets的优先级,避免“配置项在 UI 可选但不生效”。 - 统一 HTTP/DNS 在 CH-only 的上报语义(建议都走“节点文件 + Fluent Bit”,API 不再接收该流量)。
- 修复 file_clickhouse 空路径策略启动失败(要求路径 or 统一默认路径回填到 options)。
- 修复 DNS requestId 生成(全局原子递增或更高精度时间戳方案)。
8. 当前可用性判断
- 系统“可运行”,但配置行为存在歧义,且在高并发下会放大成本和排障难度。
- 若目标是稳定的高吞吐日志链路,建议优先处理 P0/P1 问题后再继续线上放量。