目录

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 的具体使用,请移步文章:

一文学会 golang 的 panic 、recover 概念和实战(集成 gin 框架/打印堆栈)

版权声明

未经授权,禁止转载本文章。
如需转载请保留原文链接并注明出处。即视为默认获得授权。
未保留原文链接未注明出处或删除链接将视为侵权,必追究法律责任!

本文原文链接: https://fiveyoboy.com/articles/go-recover-stack-log/

备用原文链接: https://blog.fiveyoboy.com/articles/go-recover-stack-log/