Files
Genarrative/docs/technical/RUST_SHARED_LOGGING_CRATE_DESIGN_2026-04-21.md
kdletters cbc27bad4a
Some checks failed
CI / verify (push) Has been cancelled
init with react+axum+spacetimedb
2026-04-26 18:06:23 +08:00

5.0 KiB
Raw Blame History

Rust shared-logging crate 设计

日期:2026-04-21

1. 文档目的

这份文档用于明确 server-rs/ 下统一日志模块的落地方式。

目标是把当前仅存在于 crates/api-server/src/logging.rs 的日志初始化逻辑,上提为一个可被多 crate 复用的独立 shared-logging crate并固定

  1. 统一日志模块的职责边界
  2. api-server、后续 spacetime-module、测试支撑与脚本入口的复用方式
  3. 日志过滤、subscriber 初始化、输出风格的统一口径
  4. 不允许继续把日志初始化散落到各主工程 crate 中

2. 当前基线

当前 Rust 工作区里的日志实现现状:

  1. api-server 内部已有 src/logging.rs
  2. 该文件负责创建 EnvFilter 并初始化 tracing subscriber
  3. main.rs 直接调用 init_tracing(&config)
  4. 其它 crate 尚未复用同一套日志初始化逻辑

当前问题:

  1. 日志初始化逻辑被绑定在 api-server 内部,无法作为工作区级共享能力复用
  2. 后续 spacetime-module、测试支撑、独立 worker、脚本入口若需要日志会继续复制粘贴
  3. 当前没有独立 crate 作为“统一日志模块”承接输出风格、默认过滤器与 subscriber 初始化边界

3. crate 职责边界

3.1 shared-logging 负责

  1. 提供工作区统一的 tracing subscriber 初始化入口
  2. 提供统一的日志过滤器解析逻辑
  3. 固定当前阶段的输出风格,例如 compactwith_target(true)
  4. api-server、后续 spacetime-module、测试支撑与独立入口提供可复用初始化函数

3.2 它不负责

  1. 保存业务日志事件结构体
  2. 直接耦合 Axum 中间件或 TraceLayer
  3. 处理业务 request id、response headers、error body
  4. 承担供应商日志上报、链路追踪采样、远端日志聚合

3.3 与其他 crate 的边界

  1. shared-logging 只提供“日志基础设施初始化”
  2. api-server 继续负责 HTTP 访问日志的 TraceLayer 挂载
  3. request_context、错误中间件、响应头模块继续负责 request id 与响应元信息串联
  4. 若未来需要结构化埋点或审计事件,应进入对应业务 crate不进入 shared-logging

4. 目录与命名

统一落位:

  1. server-rs/crates/shared-logging

当前阶段建议最小文件结构:

server-rs/crates/shared-logging/
├─ Cargo.toml
├─ README.md
└─ src/
   └─ lib.rs

说明:

  1. 当前阶段只做库 crate不做独立二进制入口
  2. api-serversrc/logging.rs 迁出后,直接依赖 shared-logging

5. API 设计

当前阶段建议提供以下最小 API

  1. init_tracing(log_filter: &str) -> Result<(), io::Error>
  2. resolve_env_filter(default_filter: &str) -> EnvFilter

设计原因:

  1. api-server 当前只需要一个初始化入口
  2. 后续如 spacetime-module 需要不同默认过滤器,也可以复用 resolve_env_filter(...)
  3. 避免在第一版就过度设计成复杂 builder

6. 配置约定

当前阶段仍保留现有配置来源:

  1. api-server 默认读取 GENARRATIVE_API_LOG
  2. 若环境变量未提供,则回落到配置对象中的 log_filter
  3. shared-logging 不直接读取业务配置结构,只消费最终传入的默认 filter 字符串

这样做的原因:

  1. 保持 shared-logging 对上层业务配置解耦
  2. 避免把 AppConfig 类型反向沉到共享基础设施 crate

7. 输出风格约定

当前阶段固定沿用现有输出口径:

  1. compact
  2. with_target(true)
  3. 基于 EnvFilter 做过滤

说明:

  1. 先保证工作区统一
  2. 后续若要引入 JSON 输出、环境区分或远端采集,再在 shared-logging 中集中演进

8. 落地规则

8.1 api-server

必须调整为:

  1. 删除本地 src/logging.rs
  2. Cargo.toml 中引用 shared-logging
  3. main.rs 改为调用 shared_logging::init_tracing(...)

8.2 其它 crate

后续若需要日志初始化,统一按以下规则:

  1. 优先依赖 shared-logging
  2. 不再在各自 crate 内重复实现一份 init_tracing

9. 不允许的设计漂移

后续实现时禁止出现以下情况:

  1. 再为 api-serverspacetime-module 各自复制一份 subscriber 初始化逻辑
  2. AxumTraceLayer 直接塞进 shared-logging
  3. 把 request id、响应头、错误 envelope 这些 HTTP 语义放进 shared-logging
  4. 为了抽象而把业务配置类型强耦合进共享日志 crate

10. 本任务完成定义

当以下条件满足时,统一日志模块任务视为完成:

  1. shared-logging crate 已创建并加入 workspace
  2. api-server 已改为依赖 shared-logging
  3. api-server/src/logging.rs 已被移除
  4. 工作区文档与任务清单已同步到“统一日志模块”口径

11. 依据文件

  1. server-rs/crates/api-server/src/logging.rs
  2. server-rs/crates/api-server/src/main.rs
  3. server-rs/crates/api-server/src/config.rs
  4. server-rs/crates/api-server/README.md
  5. backend-rewrite-tasklist/01_M0_M2_FOUNDATION_AND_AUTH.md