Files
hms/docs/archive/superpowers-completed/2026-04-26-observability-and-ops.md
iven 18fa6ce6d4 docs: 全局文档梳理归档 — 删除过期文件 + 归档 V1/早期设计 + wiki 数据校正 + CLAUDE.md 规则优化
**根目录清理:**
- 删除 CLAUDE-1.md(ZCLAW 旧项目配置,HMS 已完全脱离)
- 移动 DESIGN.md → docs/archive/(ERP 旧设计系统)
- 删除 plans/ 98 个临时会话计划文件

**归档重组:**
- V1 审计(12 文件)→ docs/archive/audits-v1/
- 早期 CRM/插件迭代设计(13 文件)→ docs/archive/superpowers-early/
- 已完成/已取代设计(28 文件)→ docs/archive/superpowers-completed/
- 早期讨论/测试报告 → docs/archive/discussions-early/ + test-reports-early/
- QA 重复文件清理(3 个旧版 result 文件)

**wiki 数据校正:**
- 迁移数 137→145,源文件 599→649,提交数 720→800+
- 小程序文件 124→163,Web 前端 297→332
- 后端测试 999→943(实际统计),权限码 75+→128
- 文档索引新增归档目录说明

**CLAUDE.md 规则优化:**
- §2.5 闭环工作法:提交+文档+推送三合一 + wiki 更新触发条件
- §2.6 Feature DoD:新增文档一致性检查项
- §6 反模式:新增 wiki 更新滞后/推送不及时警告
2026-05-15 09:29:04 +08:00

6.6 KiB
Raw Blame History

可观测性与运维基础设施实施计划

设计规格: docs/superpowers/specs/2026-04-26-observability-and-ops-design.md 日期: 2026-04-26 | 总周期: 7-9 天


Phase 1: 健康检查 + Prometheus 指标Day 1-2

Task 1: 深度健康检查端点

涉及文件:

  • 修改: crates/erp-server/src/handlers/health.rs

步骤:

  1. 拆分为两个端点:
    • GET /health/live — 存活探针(仅返回 { status: "ok" },不依赖任何外部服务)
    • GET /health/ready — 就绪探针(验证 DB ping + Redis ping + 模块状态)
  2. /health/ready 实现:
async fn health_ready(State(state): State<AppState>) -> Json<HealthResponse> {
    let db_ok = sql_query("SELECT 1").execute(&state.db).await.is_ok();
    let redis_ok = state.redis.ping().await.is_ok();
    Json(HealthResponse { status: if db_ok && redis_ok { "ok" } else { "degraded" }, db: db_ok, redis: redis_ok, ... })
}
  1. 保持旧 GET /health 兼容(重定向到 /health/ready

验收: /health/ready 在 DB/Redis 正常时返回 200任一不可达时返回 503 + 降级详情

Task 2: Prometheus 指标基础

涉及文件:

  • 修改: crates/erp-server/Cargo.toml(添加 metrics + metrics-exporter-prometheus 依赖)
  • 新增: crates/erp-server/src/middleware/metrics.rs
  • 修改: crates/erp-server/src/main.rs(注册 metrics middleware + 路由)

步骤:

  1. Cargo.toml 添加:
metrics = "0.24"
metrics-exporter-prometheus = "0.16"
  1. 创建 metrics.rs Axum middleware
    • 记录每个请求的 http_request_duration_seconds(直方图,按 method/path/status 标签)
    • 记录 http_requests_total(计数器)
  2. main.rs 启动 Prometheus exporter/metrics 端点,端口 9090
  3. 在 AppState 中注册 metrics recorder

验收: curl localhost:9090/metrics 返回 Prometheus 格式指标,包含请求延迟直方图

Task 3: DB 连接池 + EventBus 积压指标

涉及文件:

  • 修改: crates/erp-server/src/main.rs
  • 修改: crates/erp-core/src/events.rs

步骤:

  1. DB 连接池指标:每 30 秒采样 db_pool_connections_active / db_pool_connections_idle
  2. EventBus 积压指标:在 publish() 中递增 eventbus_pending_total,在 relay 处理后递减
  3. /metrics 端点暴露

验收: /metrics 包含 DB 连接池使用率和事件积压计数


Phase 2: OpenTelemetry + 生产 DockerDay 3-5

Task 4: OpenTelemetry 条件集成

涉及文件:

  • 修改: crates/erp-server/Cargo.toml(添加 opentelemetry + tracing-opentelemetry + opentelemetry-otlpoptional feature
  • 新增: crates/erp-server/src/telemetry.rs
  • 修改: crates/erp-server/src/main.rs

步骤:

  1. 添加 optional 依赖:
[features]
tracing = ["opentelemetry", "tracing-opentelemetry", "opentelemetry-otlp"]
  1. 创建 telemetry.rs:条件初始化 OpenTelemetry tracer环境变量 ERP__TELEMETRY__ENABLED=true 时启用)
  2. 配置 OTLP exporter默认 http://localhost:4317,可通过环境变量覆盖)
  3. main.rs 的 tracing subscriber 中条件注册 OpenTelemetry layer
  4. 在 SeaORM 的 DatabaseConnection 包装中添加 span记录查询耗时

验收: 启用后 Jaeger/Tempo 可看到请求 → SQL 查询 → 事件发布的完整链路;不启用时零开销

Task 5: 生产 Docker 多阶段构建

涉及文件:

  • 新增: Dockerfile(项目根目录)
  • 新增: docker/docker-compose.production.yml

步骤:

  1. 多阶段 Dockerfile:
# Stage 1: Build
FROM rust:1.82-bookworm AS builder
COPY . /app
RUN cargo build --release -p erp-server

# Stage 2: Runtime
FROM debian:bookworm-slim
COPY --from=builder /app/target/release/erp-server /usr/local/bin/
COPY --from=builder /app/crates/erp-server/config/default.toml /etc/erp/config.toml
EXPOSE 3000 9090
CMD ["erp-server"]
  1. docker-compose.production.yml:
    • erp-server 服务(限制 1 CPU / 512MB
    • PostgreSQL 16 + Redis 7 作为独立服务
    • 健康检查配置(使用 /health/ready
    • 环境变量注入JWT secret / DB URL / Redis URL 通过 secrets

验收: docker build -t hms-server . 成功,运行时镜像 < 80MB

Task 6: 前端生产构建 + Nginx

涉及文件:

  • 新增: apps/web/Dockerfile
  • 新增: apps/web/nginx.conf

步骤:

  1. 多阶段构建node 构建 → nginx 运行
  2. Nginx 配置SPA fallback + /api 代理到后端 3000 端口

验收: Docker 内前端可正常访问API 代理工作


Phase 3: 日志聚合 + 告警Day 5-7

Task 7: Grafana Loki 日志集成

涉及文件:

  • 新增: docker/loki-config.yaml
  • 修改: docker/docker-compose.production.yml

步骤:

  1. 在 production compose 中添加 Loki + Promtail 服务
  2. Promtail 配置:读取 erp-server 的 JSON 日志输出
  3. Grafana 数据源配置Loki + Prometheus

验收: Grafana 可查询和过滤后端日志

Task 8: Prometheus 告警规则

涉及文件:

  • 新增: docker/alert-rules.yml

步骤:

  1. 定义 5 条告警规则:
- alert: HighRequestLatency    # P95 > 2s 持续 5 分钟
- alert: HighErrorRate          # 5xx 比率 > 5% 持续 3 分钟
- alert: EventBusBacklog        # 积压事件 > 100 持续 5 分钟
- alert: DatabasePoolExhausted  # 活跃连接 > 90% 持续 2 分钟
- alert: HealthCheckDegraded    # /health/ready 非 ok 持续 1 分钟
  1. 配置 Alertmanager 通知渠道Webhook/邮件)

验收: 触发告警条件时 Alertmanager 发送通知

Task 9: Grafana Dashboard 模板

涉及文件:

  • 新增: docker/grafana/dashboards/hms-overview.json

步骤:

  1. 创建 HMS Overview Dashboard包含面板
    • 请求速率 + 延迟分布P50/P95/P99
    • 错误率趋势(按 status code 分组)
    • DB 连接池使用率
    • EventBus 发布/消费速率
    • 健康检查状态

验收: Dashboard 展示实时指标

Task 10: 运维文档

涉及文件:

  • 新增: wiki/observability.md

步骤:

  1. 记录监控端点(/health/live, /health/ready, /metrics
  2. 记录告警规则和响应流程
  3. 记录日志查询方法Grafana Loki
  4. 记录 Docker 部署命令

验收: 新团队成员可通过文档独立部署和排查问题


执行原则

  1. 条件编译 — OpenTelemetry 使用 feature gate不启用时零开销
  2. 渐进式 — Phase 1 可独立上线无外部依赖Phase 2/3 需要 Docker 环境
  3. 性能优先 — 指标收集使用 metrics crate 的无锁实现,不影响请求延迟
  4. 端口分离 — 业务 API (3000) + Metrics (9090) 分离,避免暴露内部指标