Files
planet/docs/plans/enterprise-logging-system-plan.md
2026-04-23 17:57:35 +08:00

666 lines
13 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.
# Planet 企业级日志系统规范与落地计划
## 目标
为 Planet 建立一套可持续演进的日志体系,覆盖:
1. 后端运行日志
2. 前端浏览器端错误与关键业务日志
3. 超级管理员操作审计
4. 高价值事件持久化
5. 实时排障与历史追溯并存
最终目标不是“把所有输出都收进一个页面”,而是建立:
- 统一日志字段规范
- 统一事件命名规范
- 统一采集与查询链路
- 清晰的实时日志层与持久化事件层分工
## 当前现状
项目当前已经具备一部分基础:
- 后端日志可从 `/tmp/planet_backend.log` 查看
- 前端开发服务日志可从 `/tmp/planet_frontend.log` 查看
- AI Provider 日志可从 Docker 容器读取
- Earth 浏览器端错误可通过 API 上报并进入 Redis 缓冲
- 管理台已有“系统日志”页面,可做来源、级别、日期等筛选
### 当前落地进度
截至 2026-04-23第一阶段已经落地的能力有
- 后端新增 `request_id` 中间件,响应会回传 `X-Request-ID`
- 新增 `system_logs` / `audit_logs` 数据表模型并接入初始化流程
- Earth 浏览器端上报日志已同时写入缓冲层和 `system_logs`
- `landing-points` / `cables` 关键后端异常已写入 `system_logs`
- 超级管理员触发重启任务时会写入 `audit_logs`
当前仍未完成的部分:
- 后端统一结构化 logger 封装还没有全仓替换
- 前端统一 logger API 还没有扩展到整个控制台
- 日志页还没有提供“历史事件库”查询视图
- 采集器与调度器的关键日志还没有系统性入库
当前主要问题:
- 日志不是统一规范打点,很多地方仍然是临时性输出
- 后端没有统一 request/trace 相关字段
- 前端没有统一 logger APIEarth 端虽然已能上报,但仍偏点状能力
- 当前系统日志页以聚合查看为主,还不是企业级日志架构
- 日志历史追溯能力不足,尤其 Earth 客户端和关键业务失败事件
- 审计日志与运行日志还没有严格分层
## 设计原则
### 1. 分层而不是混存
日志分为三层:
1. 运行日志
- 面向排障、运维、链路观察
- 默认不直接写业务数据库
- 主要走 stdout / 文件 / 容器 / 日志平台
2. 高价值事件日志
- 面向历史追溯和业务排查
- 只持久化 error、warning 和关键业务失败
- 允许写数据库
3. 审计日志
- 面向管理行为留痕
- 单独建模
- 不和普通运行日志混用
### 2. 结构化优先
所有正式日志都应能拆成字段,而不是只有一句字符串。
### 3. 平台采集优先于业务数据库
全量日志走日志平台。
数据库只存:
- 高价值错误事件
- 关键业务失败事件
- 审计事件
### 4. 前后端统一事件语言
同一个问题在前端和后端应尽量共享事件命名。
例如:
- `earth.landing_points.load_failed`
- `earth.news.feed.refresh_failed`
- `system.restart_task.failed`
这样在页面、API、数据库、日志平台里都能串联查询。
### 5. 默认脱敏
日志禁止记录:
- token
- password
- cookie
- Authorization header
- 完整敏感 PII
## 日志分层规范
## 一、后端运行日志规范
### 使用方式
- 统一使用 Python `logging`
- 禁止在正式路径中使用裸 `print`
- 统一 `logger = logging.getLogger(__name__)`
### 最低字段要求
后端正式日志至少应能携带:
- `timestamp`
- `level`
- `service`
- `module`
- `event`
- `message`
- `request_id`
- `trace_id`
- `user_id``actor`
- `context`
### 等级定义
- `DEBUG`
仅开发或短期诊断使用
- `INFO`
关键流程开始、结束、状态切换
- `WARNING`
可恢复异常、降级、重试、部分失败
- `ERROR`
当前请求、任务或操作失败
- `CRITICAL`
系统级不可用、核心能力中断
### 推荐记录点
必须补日志的位置:
- API 入口请求摘要
- API 异常出口
- 定时任务启动/完成/失败
- 数据采集器启动/完成/失败
- 外部依赖失败
- 关键 Earth 业务 API 失败
推荐模式:
```python
logger.info(
"collector started",
extra={
"event": "collector.run.started",
"source": source_name,
"task_id": task_id,
},
)
```
异常必须优先使用:
```python
logger.exception("landing points build failed", extra={"event": "earth.landing_points.load_failed"})
```
## 二、前端日志规范
### 前端日志分级
前端不做“全量 console 上报”,而做三层:
1. 本地调试日志
- 保留在浏览器 console
- 不上报
2. 运行时错误
- `window.onerror`
- `unhandledrejection`
- React/Earth 模块未捕获异常
- 上报到后端日志入口
3. 关键业务事件
- 接口加载失败
- 图层初始化失败
- 巡航队列构建失败
- 页面关键模块进入降级状态
### 前端 logger API 建议
统一设计为:
```ts
logger.debug(event, message, context?)
logger.info(event, message, context?)
logger.warn(event, message, context?)
logger.error(event, message, context?)
```
最低字段要求:
- `timestamp`
- `level`
- `page`
- `module`
- `event`
- `message`
- `url`
- `user_agent`
- `context`
### 前端上报范围建议
默认上报:
- `ERROR`
- `WARNING`
- 关键业务失败 `INFO`
默认不上报:
- 调试型 `DEBUG`
- 普通开发 `console.log`
## 三、审计日志规范
审计日志单独设计,不和系统运行日志混合。
### 适用范围
- 系统重启
- 配置变更
- 数据源启停与优先级调整
- 调度策略变更
- 管理员触发采集任务
- 高权限操作
### 最低字段要求
- `timestamp`
- `actor_id`
- `actor_name`
- `action`
- `target_type`
- `target_id`
- `result`
- `ip`
- `request_id`
- `details`
## 统一事件命名规范
建议命名采用:
`<domain>.<module>.<action>.<result>`
示例:
- `earth.landing_points.load_failed`
- `earth.news.feed.refreshed`
- `earth.news.cruise_queue.built`
- `system.logs.snapshot_requested`
- `system.restart_task.started`
- `system.restart_task.failed`
- `datasource.collector.run_failed`
- `settings.system.updated`
规则:
- domain 使用稳定业务域
- module 指实际模块
- action 使用动词
- result 使用过去时或结果词
## 企业级目标架构
推荐采用“双轨架构”:
1. 实时运行日志轨
2. 高价值持久化事件轨
```mermaid
flowchart LR
A["Frontend / Earth"] --> B["Frontend Logger"]
C["Backend API / Scheduler / Collectors"] --> D["Backend Logger"]
B --> E["Log Ingest API"]
D --> F["stdout / file / docker logs"]
F --> G["Log Collector"]
G --> H["Log Platform (Loki / ELK / Datadog)"]
E --> I["High-value Event Filter"]
D --> I
I --> J["PostgreSQL system_logs / audit_logs"]
H --> K["Ops Search / Alerting"]
J --> L["Admin Logs UI / History Query"]
```
### 实时运行日志层
职责:
- 低延迟排障
- 实时观察
- 全文检索
- 告警触发
推荐落地:
- 开发期:文件 + Docker + 管理台聚合查看
- 标准化阶段Fluent Bit / Vector -> Loki 或 ELK
### 高价值事件层
职责:
- 长期追溯
- 按业务事件检索
- 与产品页面、管理台联动
推荐落地:
- PostgreSQL `system_logs`
- PostgreSQL `audit_logs`
## 数据库设计建议
## 一、`system_logs`
只存高价值运行事件,不存全量流水。
建议字段:
- `id`
- `occurred_at`
- `source`
- `service`
- `module`
- `event`
- `level`
- `message`
- `request_id`
- `trace_id`
- `user_id`
- `category`
- `context`
- `retention_class`
- `created_at`
### 典型 source
- `backend`
- `frontend`
- `earth-client`
- `scheduler`
- `collector`
- `ai-provider`
### 典型 retention_class
- `short_term`
- `incident`
- `audit_linked`
## 二、`audit_logs`
建议字段:
- `id`
- `occurred_at`
- `actor_id`
- `actor_name`
- `action`
- `target_type`
- `target_id`
- `result`
- `request_id`
- `ip`
- `details`
- `created_at`
## 系统日志页面演进目标
当前日志页已经有基础能力,但企业级目标应拆成两个视图:
1. 实时日志视图
- 来源
- 级别
- 日期范围
- 实时刷新
- 原始日志查看
2. 历史事件视图
- 查询 `system_logs`
- 查询 `audit_logs`
- 支持按事件名、来源、级别、时间范围、用户筛选
不建议让同一个视图同时承担:
- 全量运行日志
- 审计日志
- 业务事件历史
推荐分 Tab 或分页面。
## 分阶段落地计划
## 第一阶段:统一规范与最小治理
### 目标
把当前零散日志行为统一起来,为后续平台化做准备。
### 任务
1. 后端统一 logger 入口
- 清理裸 `print`
- 补齐关键异常 `logger.exception`
- 统一关键 event 名称
2. 前端统一 logger API
- 为 Earth 和管理台提供统一日志封装
- 收敛浏览器端错误上报
3. 日志字段规范文档落地
- 在仓库中固定字段、事件命名、级别约定
### 验收标准
- 后端关键失败路径不再依赖 `print`
- Earth 端关键失败通过统一 API 上报
- 新代码使用统一 event 命名
## 第二阶段:上下文打通
### 目标
让前后端日志可串联。
### 任务
1. 后端增加 `request_id`
- 中间件生成并注入
- 响应头回传
2. 前端请求链带上 `request_id`
- 或至少在错误展示中保留后端返回 request id
3. 关键接口补 `trace` 相关上下文
### 验收标准
- 单个失败请求可以从前端提示一路查到后端日志
- 系统日志页可展示 request id 或关联字段
## 第三阶段:高价值事件入库
### 目标
建立真正的历史追溯能力。
### 任务
1. 新增 `system_logs`
2. 新增 `audit_logs`
3. 持久化以下内容:
- Earth 客户端错误
- 后端 `ERROR/WARNING`
- 关键业务失败事件
- 超级管理员操作审计
4. 管理台增加历史事件查询
### 验收标准
- 服务重启后仍能查到关键错误
- Earth 侧错误不依赖 Redis TTL 才能追踪
- 管理员关键操作有审计记录
## 第四阶段:日志平台接入
### 目标
把全量运行日志从“页面聚合查看”升级为标准日志平台。
### 推荐技术路线
可选方案 A
- Fluent Bit
- Loki
- Grafana
可选方案 B
- Filebeat
- Elasticsearch
- Kibana
### 任务
1. 统一 stdout / file / docker 输出接入 collector
2. 接入集中日志平台
3. 配置基础检索与告警规则
### 验收标准
- 可按 service / level / event / request_id 检索
- 可做错误率和高频事件趋势观察
- 可配置告警
## 第五阶段:日志治理与成本控制
### 目标
控制噪音、成本和维护复杂度。
### 任务
1. 明确保留策略
- 实时日志平台保留周期
- `system_logs` 保留周期
- `audit_logs` 保留周期
2. 限制 DEBUG/INFO 噪音
3. 脱敏检查
4. 高价值事件分级
### 验收标准
- 数据量可控
- 日志可用性提升而不是噪音堆积
- 无敏感信息泄露
## 开发任务拆分
## A. 后端
### A1. 日志中间件
- 新增 request id middleware
- 注入 logger context
- 响应头透出 request id
### A2. logger 封装
- 提供统一 helper
- 统一 event 与 context 传法
### A3. 高价值日志落库
- 新增 model / migration
- 新增写入 service
- 对关键异常和 Earth ingest 进行入库
### A4. 审计日志
- 对 system control、settings、datasource 管理接口补 audit
## B. 前端
### B1. logger SDK
- `logger.error/warn/info/debug`
- 自动补 page、module、url
### B2. Earth 接入
- 图层加载
- 新闻模块
- 巡航模块
- 关键交互失败
### B3. 管理台接入
- 系统控制页面
- 设置页
- 数据源管理页
### B4. 日志页面
- 分离实时视图与历史视图
- 补 request id / event / source / level 查询
## 里程碑建议
### M1. 规范收口
- 输出统一日志规范
- 清理核心裸输出
### M2. 请求链串联
- request id 打通
### M3. 关键事件落库
- `system_logs` + `audit_logs`
### M4. 平台化
- Loki/ELK 接入
## 风险与取舍
### 风险 1直接全量入库
不建议。
问题:
- 数据膨胀快
- 检索体验差
- 业务库压力增加
### 风险 2只做实时日志不做高价值持久化
不够。
问题:
- 故障后无法追溯
- 前端错误容易因 TTL / 重启丢失
### 风险 3没有事件命名治理
问题:
- 页面能看日志,但无法做稳定聚合与检索
## 推荐实施顺序
最推荐的实际推进顺序:
1. 统一后端/前端 logger 规范
2. 打通 request id
3. 新增 `system_logs``audit_logs`
4. 只持久化高价值事件
5. 最后接日志平台
这是对当前 Planet 成本最低、收益最高、也最接近企业级实践的路线。
## 本计划的最终验收
当以下条件满足时,可认为日志系统初步达到企业级可用水平:
- 后端关键失败路径都有结构化日志
- Earth 前端关键失败可统一上报
- 管理员关键操作可审计
- 高价值错误可长期追溯
- 实时日志与历史事件分层明确
- 至少有 request_id 或等价链路串联能力
- 日志页不再只是“看文件”,而是具备查询真实事件的能力