当我们使用recover捕获到异常时

func TestPanic() {
	defer func() {
		if info := recover(); info != nil {
			logger.GetNewLogger(consted.ServiceName).Panic("test panic: ", info)
		}
	}()
	var a []int
	pa := a[6]
	fmt.Println(pa)
}

我们仅仅只能得到panic的基础信息:

2022-03-28T15:02:22.989+0800	panic	D:/gocode/framework/alert_center/main.go:51	test panic: runtime error: index out of range [6] with length 0

我们只能知道是某一段代码内(包含调用)出现了panic,并不能准确知道错误出现在哪。但是如果我们看控制台输出,是能看到提示代码行数的,那么我们怎么拿到这些信息,也输出到我们的日志中呢?
我们只需要拿到panic时的堆栈信息即可。

func PanicTrace(err interface{}) string {
	buf := new(bytes.Buffer)
	fmt.Fprintf(buf, "%v\n", err)
	for i := 1; ; i++ {
		pc, file, line, ok := runtime.Caller(i)
		if !ok {
			break
		}
		fmt.Fprintf(buf, "%s:%d (0x%x)\n", file, line, pc)
	}
	return buf.String()
}

//

func TestPanic() {
	defer func() {
		if info := recover(); info != nil {
			logger.GetNewLogger(consted.ServiceName).Panic("test panic: \n", PanicTrace(info))
		}
	}()
	var a []int
	pa := a[6]
	fmt.Println(pa)
}

这样就可以拿到堆栈信息,并保存到我们自己的日志文件中了

2022-03-28T15:12:31.881+0800	panic	D:/gocode/framework/alert_center/main.go:33	test panic: 
runtime error: index out of range [6] with length 0
D:/gocode/framework/alert_center/main.go:33 (0x10ece74)
C:/Program Files/Go/src/runtime/panic.go:971 (0x7f39e5)
C:/Program Files/Go/src/runtime/panic.go:88 (0x7f0e29)
D:/gocode/framework/alert_center/main.go:51 (0x10ec96d)
D:/gocode/framework/alert_center/main.go:36 (0x10ec4f3)
C:/Program Files/Go/src/runtime/proc.go:225 (0x7f6735)
C:/Program Files/Go/src/runtime/asm_amd64.s:1371 (0x82efe0)