Skip to main content

Go: 标准库 trace

📅 2026-03-19 ✏️ 2026-03-19 Go 标准库 CS GO

1 · 标准库 trace#

runtime/trace 用于记录程序运行时的细粒度事件时间线

pprof(采样型,“CPU 花在哪”)不同,trace 是事件型,展示完整的时间线因果关系,适合诊断延迟、调度抢占、goroutine 饥饿、GC 影响等时序相关的性能问题。

使用trace的三步骤:埋点 → 采集 → 分析

1.1 · 1. 埋点(Instrumentation)#

1.1.1 · 运行时自动埋点

Go runtime 内置,无需代码:

  • Goroutine 创建/阻塞/唤醒/结束
  • GC 各阶段(STW、标记、清扫)
  • Syscall 进入/退出/阻塞
  • 网络轮询事件、P 启停、堆大小变化

1.1.2 · 自定义埋点(User Annotation)#

类型说明API
Log打一个点:记录某个事件发生Log(ctx, category, message)
Region量一段区间:某个操作耗时多久,支持嵌套WithRegion(ctx, type, fn) / StartRegion
Task串一条链:跨 goroutine 的逻辑操作关联起来NewTask(ctx, type)task.End()
ctx, task := trace.NewTask(ctx, "makeCappuccino")
trace.Log(ctx, "orderID", orderID)

go func() {
	trace.WithRegion(ctx, "steamMilk", steamMilk)
	milk <- true
}()
go func() {
	defer task.End()
	<-milk
	trace.WithRegion(ctx, "mixMilkCoffee", mixMilkCoffee)
}()

1.2 · 2. 采集(Collection)#

// 方式一:代码中手动控制
f, _ := os.Create("trace.out")
trace.Start(f)
defer trace.Stop()

// 方式二:测试时采集
// go test -trace=trace.out ./...

// 方式三:HTTP 接口(运行中的服务)
import _ "net/http/pprof" // 注册 /debug/pprof/trace
// curl -o trace.out http://localhost:6060/debug/pprof/trace?seconds=5

1.3 · 3. 分析(Analysis)#

# 打开 Web UI 查看时间线(需 Chrome)
go tool trace trace.out

# 生成 pprof 格式 profile
go tool trace -pprof=TYPE trace.out
# TYPE: net(网络阻塞) / sync(同步阻塞) / syscall(系统调用阻塞) / sched(调度延迟)

2 · 黑盒子 FlightRecorder#

go doc trace.FlightRecorder

典型用途:程序常态运行时开着 FlightRecorder,出问题时调用 WriteTo 把最近几秒的 trace 导出,用于事后分析。

相比 trace.Start/Stop 需要提前预知何时采集,FlightRecorder 是”先录着,出事再看。

如何实现:持续滚动记录最近的 trace 数据,只保留一个滑动窗口(通过 MinAge / MaxBytes 控制)。