Rust in Everything
基于 tracing 0.1.44

tracing 源码解析

tracing 仓库里的 crate 各自发版、各自打 tag,这一卷的四个主角也就各有各的 tag,每个 crate 都对着自己的 tag 读,源码链接和行号也从各自的 tag 取:

crate版本tagcommit日期
tracing0.1.44tracing-0.1.442d55f6fa2025-12-18
tracing-core0.1.36tracing-core-0.1.3610a9e8382025-12-18
tracing-attributes0.1.31tracing-attributes-0.1.31550862312025-11-26
tracing-subscriber0.3.23tracing-subscriber-0.3.2354ede4d52026-03-13

另有两个 crate 只在一两节出现:tracing-log 0.2.0(tag tracing-log-0.2.0)讲 log 互通,tracing-appender 0.2.5(tag tracing-appender-0.2.5)出现在常见坑里。为什么不能只用一个 tag,见怎么读这一卷。

tracing 由 Tokio 项目维护,但不依赖 tokio。异步那一章讲 Instrumented 怎么在每次 poll 时进出 span,poll 本身链回 tokio 卷;tower-http 的 TraceLayer 在 axum 卷讲过,这里只链过去。

tracing 做的事分成两件,全卷沿这两条线展开:

  • 事件主线(每次 info!):宏在调用点展开成一个 static 的调用点和一段判断,依次过四道门:编译期的 STATIC_MAX_LEVEL、全局的 LevelFilter::current()、调用点缓存的 Interest、当前 subscriber 的 enabled。都通过才构造字段、调用 Event::dispatch,tracing-subscriber 的 Layered 把事件交给每个 Layer::on_event,fmt::Layer 把它格式化成一行写出去。
  • span 主线(一个 span 的一生):info_span! 过同样的门,subscriber 的 new_span 分配一个 span::Id;enter 把它压进当前线程的 span 栈,守卫 drop 时出栈;Span 的 clone 和 drop 增减引用计数,归零时 try_close,所有 layer 的 on_close 跑完才释放 span 的数据。
flowchart TB
  intro[00 导读] --> overview[01 全景]
  overview --> core[02 tracing-core]
  core --> facade[03 tracing 门面]
  facade --> attrs["04 #[instrument]"]
  facade --> sub[05 tracing-subscriber]
  attrs --> design[06 设计取舍]
  sub --> design
  design --> pit[07 常见坑]
  pit --> site[08 在本站中]
  site --> hands[09 动手]

各部分

  1. 00 导读:锁定的版本,两条主线,阅读路线;仓库里的 crate、feature 和 src/ 目录。
  2. 01 全景:tracing 解决什么问题;一个最小程序把两条主线跑一遍。
  3. 02 tracing-core:本卷重点。Metadata 与 Level、调用点与 Interest 缓存、Dispatch、Subscriber trait、字段、span 与 Event 的数据。
  4. 03 tracing 门面:宏展开成什么、级别过滤的几道门、Span 与 Entered、Instrument 与异步、和 log 互通。
  5. 04 #[instrument]:属性宏展开成什么,以及它的参数。
  6. 05 tracing-subscriber:Layer 与 Layered、Registry、全局与每层过滤、EnvFilter、fmt、reload。
  7. 06 设计取舍:把各章的取舍汇总到一起。
  8. 07 常见坑:用报错原文或现象做标题,讲它在源码里怎么产生。
  9. 08 在本站中:本站(开源)代码里怎么装 subscriber、怎么用 #[instrument]。
  10. 09 动手:不用 tracing,从零写一个带调用点缓存的最小日志门面。

从「导读」开始。只想会用 tracing 的读者,读 01 全景、03 tracing 门面、04 #[instrument]、05 里的 fmt 和 EnvFilter,以及常见坑;想读懂实现的,按顺序读,02 是全卷的重点:两条主线上的每一步最后都落到 tracing-core 的类型上。

💬 关联讨论

发起讨论
加载中...