使用协程id调试和跟踪你的接口(非侵入式)
go的上下文是必须明确传递Context
的,按这种方式,如果你需要调试一个接口全部执行了多少sql, 打印了多少log, 那么就需要侵入式修改你的代码,每个函数都要多穿参数,明显不够友好,而且在非调试下影响性能。
go每个协程都会分配一个唯一id, 调试程序可以根据它跟踪你的执行过程,但是呢go为了安全,默认不公开goroutine id。
获取它有两个途径。
- 可以在运行时包的字符串信息获取
- go源码是公开的,本地环境直接修改公开它
这里使用第一个方法
// 获取跟踪ID, 严禁非开发模式使用
// github.com/bigwhite/experiments/blob/master/trace-function-call-chain/trace3/trace.go
func getGoId() uint64 {
b := make([]byte, 64)
b = b[:runtime.Stack(b, false)]
b = bytes.TrimPrefix(b, []byte("goroutine "))
b = b[:bytes.IndexByte(b, ' ')]
n, _ := strconv.ParseUint(string(b), 10, 64)
return n
}
运用在 gin 中间件
记录每个API, 所有运行过程,包括请求参数、运行时间、执行sql、打印log、响应内容。
TODO 稍等更新,我需要声望