因为panic会自动打印堆栈信息,但是为了程序继续运行使用了recover,为了像panic那样也打印堆栈,可以在日志里使用debug.Stack():
func SysRecoverWrap(f func()) func() {
return func() {
defer func() {
if r := recover(); r != nil {
log.Errorf("SYSTEM ACTION PANIC: %v, stack: %v", ToErr(r), string(debug.Stack()))
}
}()
f()
}
}
堆栈打印实例:
package main
import (
"fmt"
"runtime/debug"
)
func test1() {
test2()
}
func test2() {
test3()
}
func test3() {
// 可以通过 debug.PrintStack() 直接打印,也可以通过 debug.Stack() 方法获取堆栈然后自己打印
fmt.Printf("%s", debug.Stack())
debug.PrintStack()
}
func main() {
test1()
}
------------------------------------
$ go run test_stacktrace.go
goroutine 1 [running]:
runtime/debug.Stack(0x0, 0x0, 0x0)
/usr/lib/golang/src/runtime/debug/stack.go:24 +0x80
main.test3()
/tmp/test_stacktrace.go:17 +0x24
main.test2()
/tmp/test_stacktrace.go:13 +0x14
main.test1()
/tmp/test_stacktrace.go:9 +0x14
main.main()
/tmp/test_stacktrace.go:22 +0x14
goroutine 1 [running]:
runtime/debug.Stack(0x0, 0x0, 0x0)
/usr/lib/golang/src/runtime/debug/stack.go:24 +0x80
runtime/debug.PrintStack()
/usr/lib/golang/src/runtime/debug/stack.go:16 +0x18
main.test3()
/tmp/test_stacktrace.go:18 +0x101
main.test2()
/tmp/test_stacktrace.go:13 +0x14
main.test1()
/tmp/test_stacktrace.go:9 +0x14
main.main()
/tmp/test_stacktrace.go:22 +0x14