常见坑
每一章对着一个报错或一个现象:先用最小的程序把它复现出来(编译错误引用 rustc 1.99.0 的原文),再到源码里找它从哪一行来,最后给出修法和检查办法。机制在前面章节讲过的,这里只链过去,不再重复。
- Unable to install global subscriber:
init第二次调用时 panic,两种入口两种前缀;测试里每个测试都init;try_init的错误可能是全局 subscriber 没装上,也可能是装上了、只是log那边被占了,let _ =把两者一起吞掉。 - 一条日志都没有:没装 subscriber;
let _ = set_default(..)的守卫当场 drop;set_default只管当前线程,tokio 多线程运行时里 spawn 出去的任务什么都不打。 - RUST_LOG 设了不生效:
my-app=debug对不上 targetmy_app,连 ERROR 都没了;逗号后的空格让一段指令解析失败;空的RUST_LOG=让try_from_default_env返回一个什么都不放行的过滤器。 - 跨 .await 持有 span.enter():日志挂到别的 span 上;clippy 默认不报,要配
await_holding_invalid_type;改用.instrument(span)。 - release 构建里 debug! 全部消失:某个依赖开了
release_max_level_*,feature 合并后对整个程序生效。 #[instrument]报 doesn't implementDebug:参数默认按Debug记录,用skip/skip_all;err要求Display。#[instrument]的 target 和 parent 一起写报错:tracing-attributes 0.1.31 重复检查写错了字段,换个参数顺序可以绕过。- Span::record 没有效果:字段没在创建 span 时声明,要先写成
field::Empty。 - 文件记 debug、终端记 info,结果两边一样:
.with(filter)是全局过滤,要用layer.with_filter(..)。 - 日志重复:tracing 开了
log-always又装了LogTracer。 - tracing-appender 日志全丢:
non_blocking返回的WorkerGuard被立刻 drop,进程退出前缓冲里的日志没写完。 - 测试里的日志:
fmt().init()写 stdout,绕过 libtest 的输出捕获;with_test_writer()才走print!。
flowchart TB setup["装 subscriber 时"] --> p1["1 init 两次"] setup --> p2["2 一条都没有"] setup --> p10["10 日志重复"] setup --> p11["11 appender 丢日志"] setup --> p12["12 测试里的日志"] gate["过滤的几道门"] --> p3["3 RUST_LOG"] gate --> p5["5 release 无 debug"] gate --> p9["9 过滤对所有层"] spanline["span 主线"] --> p4["4 跨 await 持有"] spanline --> p8["8 record 无效"] compile["编译期"] --> p6["6 instrument Debug"] compile --> p7["7 target 与 parent"] p1 --> p2 p1 --> p12
前两类是事件主线的两端出了问题:一头是 Dispatch 没装对,事件根本没有去处;另一头是某道门把它挡住了。图里两条额外的线:第 1 个里被 let _ = 吞掉的 try_init 错误,常常就是第 2 个的原因;测试里的 init 冲突(第 1 个)和输出不被捕获(第 12 个)是同一段测试代码的两个问题。读之前最好先读过 Dispatch:全局与线程局部、级别过滤的几道门 和 EnvFilter。
💬 关联讨论
发起讨论加载中...