go 自带的 profiling 工具很强大(pprof, trace, GODEBUG …), 但有时我还是想不修改目标进程的源码获取它的一些
runtime 信息, 最近研究了一下 py-spy 和 delve, 发现还是可实现的, 就做了个小东西gospy.
用法
目前就两个命令: gospy summary
和 gospy top
sudo ./gospy summary --pid 1234
, 可以 dump 目标进程的一些信息和当前活动 goroutine 正在执行的函数信息,
比如对一个 prometheus 进程做一次 snapshot:
bin: /home/will/Downloads/prometheus-2.12.0.linux-amd64/prometheus, goVer: 1.12.8, gomaxprocs: 6
P0 idle, schedtick: 642, syscalltick: 81
P1 idle, schedtick: 959, syscalltick: 67
P2 idle, schedtick: 992, syscalltick: 32
P3 idle, schedtick: 581, syscalltick: 17
P4 idle, schedtick: 89, syscalltick: 8
P5 idle, schedtick: 231, syscalltick: 5
Threads: 14 total, 0 running, 14 sleeping, 0 stopped, 0 zombie
Goroutines: 44 total, 0 idle, 0 running, 5 syscall, 39 waiting
goroutines:
1 - waiting for chan receive: rt0_go (/usr/local/go/src/runtime/asm_amd64.s:202)
2 - waiting for force gc (idle): 5 (/usr/local/go/src/runtime/proc.go:240)
3 - waiting for GC sweep wait: gcenable (/usr/local/go/src/runtime/mgc.go:209)
8 - syscall: addtimerLocked (/usr/local/go/src/runtime/time.go:169)
9 - waiting for select: 0 (/app/vendor/go.opencensus.io/stats/view/worker.go:33)
16 - waiting for GC worker (idle): gcBgMarkStartWorkers (/usr/local/go/src/runtime/mgc.go:1785)
17 - waiting for finalizer wait: createfing (/usr/local/go/src/runtime/mfinal.go:156)
19 - syscall: 0 (/usr/local/go/src/os/signal/signal_unix.go:30)
22 - waiting for GC worker (idle): gcBgMarkStartWorkers (/usr/local/go/src/runtime/mgc.go:1785)
23 - waiting for GC worker (idle): gcBgMarkStartWorkers (/usr/local/go/src/runtime/mgc.go:1785)
38 - waiting for GC worker (idle): gcBgMarkStartWorkers (/usr/local/go/src/runtime/mgc.go:1785)
49 - waiting for GC worker (idle): gcBgMarkStartWorkers (/usr/local/go/src/runtime/mgc.go:1785)
50 - waiting for GC worker (idle): gcBgMarkStartWorkers (/usr/local/go/src/runtime/mgc.go:1785)
74 - waiting for select: sync (/app/scrape/scrape.go:408)
75 - syscall: addtimerLocked (/usr/local/go/src/runtime/time.go:169)
84 - syscall: addtimerLocked (/usr/local/go/src/runtime/time.go:169)
85 - waiting for select: Run (/app/vendor/github.com/oklog/run/group.go:36)
...
P0, P1 …, 是 go 的 GMP schedule 模型里的 P, 可以简单理解成对一个物理核心的逻辑抽象. 个数可由环境变量 GOMAXPROCS 控制,
默认是机器核心数.
......