GoLang Trace 详解

2020-04-15 golang

GoLang 有很多的 Profile 工具,包括了 CPU、Memory、Blocking 各种 Profiler 实现,也包括了 GC/Scheduler Tracer、Heap Dumper,这些工具大部分提供的是聚合信息,即使 Dump 这种可以查看内存对象的,也很难确定其执行过程。

于是乎,就有了 Trace 实现。

简介

Trace 工作流程非常简单,在标准库以及核心库中会记录 GoLang 运行期间的每个事件,例如内存分配、垃圾收集器、协程切换、调用阻塞等,通常有如下几种方法可以开启:

  • 运行 go test 的时候,带上 -trace=trace.out 类似参数。
  • pprof 中获取实时信息,默认通过 import _ "net/http/pprof" 导入。
  • 在代码中编码嵌入,可以根据代码自定义。

如下是简单示例。

package main

import (
	"context"
	"fmt"
	"os"
	"runtime"
	"runtime/trace"
	"sync"
)

func main() {
	runtime.GOMAXPROCS(4)

	f, err := os.Create("trace.out")
	if err != nil {
		return
	}
	defer f.Close()

	if err := trace.Start(f); err != nil {
		return
	}
	defer trace.Stop()

	ctx, task := trace.NewTask(context.Background(), "sum")
	defer task.End()

	var wg sync.WaitGroup
	wg.Add(10)
	for i := 0; i < 10; i++ {
		go func(region string) {
			defer wg.Done()
			trace.WithRegion(ctx, region, func() {
				var sum, k int64
				for ; k < 1000000000; k++ {
					sum += k
				}
				fmt.Println(region, sum)
			})
		}(fmt.Sprintf("region_%02d", i))
	}
	wg.Wait()
}

然后通过如下命令导出。

$ go run main.go
$ go tool trace trace.out

其它

gotraceui

除了上述的 Trace View 之外,还可以通过 gotraceui 查看执行结果。

参考