go 使用 recover 捕获 panic 并且打印代码堆栈日志
背景
用过 golang 的相信都知道,我们在开发中为了防止程序出现 panic ,导致整个程序宕机停止,我们通常都会使用 recover 对 panic 进行捕获,这样子程序就不会因为某个 bug panic 导致终止了,
尤其是在开启 goroutine 协程时,recover 机制显得非常好用,也是程序安全的一种手段之一
但是同时也存在一个问题,recover() 的结果在打印出来时仅有错误❌原因,并没有具体代码调用堆栈信息,这让我们在问题排查上显得有些许吃力
那么如何在 recover 的同时打印调用堆栈信息呢?实际上是可以进行打印的
实现
我们可以使用官方提供的 recover() 机制对程序 panic 进行捕获,在捕获的同时,使用 runtime.Stack 打印代码调用堆栈:
具体代码实现如下:
func main(){
defer func() {
if rec := recover(); rec != nil {
buf := make([]byte, 1<<16) // 分配 64KB 缓冲区
runtime.Stack(buf, true) // 获取完整的调用栈
log.Errorf("recover result ", string(buf)) // 记录调用栈详情
}
}()
panic("test err")
}
为什么选择
1<<16
(64KB)?普通程序的调用栈通常不会超过 64KB,这个大小能覆盖绝大多数情况
当然也不建议太大,打印日志也是有一定性能耗时的,堆栈信息足够排查问题即可
并且:在 Go 的标准库和社区实践中,
1<<16
是常见的默认值(如net/http
的调试日志)
关于 panic、recover 的具体使用,请移步文章:
版权声明
未经授权,禁止转载本文章。
如需转载请保留原文链接并注明出处。即视为默认获得授权。
未保留原文链接未注明出处或删除链接将视为侵权,必追究法律责任!
本文原文链接: https://fiveyoboy.com/articles/go-recover-stack-log/
备用原文链接: https://blog.fiveyoboy.com/articles/go-recover-stack-log/