用途
Rust tracing 是 Rust 生态中用于结构化、异步感知诊断的日志与追踪方案。资料将其定位为现代 Rust 异步服务与钱包类应用的诊断工具,用于替代传统 log crate。相比 log,tracing 同时提供事件(events)与跨度(spans,即嵌套上下文),具备异步感知能力(跨度上下文跨 .await 跟随任务)、类型化键值字段、可组合的多个订阅者(subscribers),以及按目标、按字段的动态采样与过滤,并可通过 tracing-opentelemetry 原生对接 OpenTelemetry。
主要能力
- 事件:类似日志行,提供 trace、debug、info、warn、error 等级别,支持结构化字段(如 user_id = 42),并可用 ?error(Debug 格式)或 %error(Display 格式)输出。
- 跨度:使用 info_span! 创建嵌套上下文,跨度内所有事件自动携带该跨度的字段。
- #[instrument] 属性:惯用写法,可自动为函数创建跨度;支持 skip(...) 排除参数、fields(...) 添加自定义字段、err/ret 自动记录返回值、level 指定级别、skip_all 跳过全部参数。异步场景下跨度上下文自动跨 .await 保留。
- 订阅者与过滤:通过 tracing-subscriber 初始化,使用 EnvFilter 按环境变量(如 RUST_LOG)进行全局、按 crate 或按模块过滤。
- JSON 输出:fmt().json() 输出结构化日志,可配置 with_current_span、with_span_list、flatten_event,便于接入 Loki、Elasticsearch、Datadog 等日志聚合器。
- 多层组合:Registry 可叠加多个 layer(stdout、stderr JSON、滚动文件等),每层可拥有独立过滤器。
- OpenTelemetry 导出:通过 tracing-opentelemetry 与 opentelemetry-otlp 将跨度发送到 OTel collector(Jaeger、Tempo、Honeycomb 等)。
- Tokio Console:通过 console-subscriber 与 tokio-console 实时查看任务、轮询、锁与阻塞 I/O,识别卡住的任务、争用与慢轮询。
- 移动端与 FFI:Android 通过 tracing-android 桥接到 Logcat;iOS 通过 tracing-oslog 桥接到 os_log;可用 Once 实现跨平台一次性初始化,供 Kotlin/Swift 调用。
- 隐私脱敏:通过自定义 Display 实现或 skip 字段,避免在生产日志中记录原始地址、余额、种子等敏感信息;也可用 feature flag 控制。
- 自定义 Layer:可实现 Layer trait,在 on_event 中按级别触发自定义逻辑(如 Prometheus 计数器)。
使用方式
资料给出典型流程:在 Cargo.toml 添加 tracing 与 tracing-subscriber(可选 tracing-appender、tracing-opentelemetry、opentelemetry 系列、console-subscriber);在 main 中初始化订阅者(registry + EnvFilter + fmt layer);通过 RUST_LOG 环境变量控制过滤级别;在代码中使用事件宏与跨度;需要时叠加 JSON、文件、OTel 等 layer。移动端按平台条件编译初始化对应 layer,并通过 UniFFI 导出 init_logging 供原生调用。
适用场景
现代 Rust 异步服务、钱包类应用、需要结构化日志与分布式追踪的服务、需要实时异步调试(Tokio Console)的项目,以及通过 UniFFI 向 Android/iOS 输出 Rust 核心日志的移动应用。
限制与注意事项
资料列出多项反模式与故障排查:生产日志不应使用 println!;不应记录原始密钥、余额、地址;避免在日志宏内使用 format! 造成过滤级别下的浪费;避免单一订阅者开启全部级别;spawn 任务需注意跨度上下文;文件写入应使用 tracing_appender::non_blocking 避免阻塞异步运行时;tracing-subscriber 不可重复初始化(用 try_init 或 Once);预期错误(如 404、校验失败)宜用 warn!/info! 而非 error!;OTel 导出需与 Tokio 运行时匹配;移动端不可硬编码日志路径。资料还说明 tracing 在级别被过滤时宏展开接近零成本,可用 enabled! 门控昂贵计算,并可用 TraceIdRatioBased 采样降低导出量。