package main import ( "bufio" "fmt" "github.com/pkg/errors" "os" "path/filepath" "time" ) func func1(num int64) (result int64, err error) { defer func() { rec := recover() if rec != nil { err, _ = rec.(error) err = errors.WithStack(err) // 附加调用堆栈信息 } }() // 当num的值为0时会报panic,然后被defer-recover捕获错误 result = 1024 / num return } func func2(num int64) (result int64, err error) { result, err = func1(num) // 由于发生了错误,附加调用堆栈信息然后返回即可 if err != nil { err = errors.WithStack(err) // 附加调用堆栈信息 return } return } func WriteErrorLog(err error) { curPath, _ := filepath.Abs(".") // 当前目录硬盘路径,结尾不带“/” logPath := curPath + "/log" // 错误日志文件保存目录 logFile := logPath + "/error.log" // 错误日志文件硬盘路径 // 创建日志文件保存目录(若目录存在则忽略) _ = os.MkdirAll(logPath, 0755) // 打开日志文件(不存在则创建|只写模式|尾部追加) file, _ := os.OpenFile(logFile, os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0644) // 关闭日志文件 defer func(file *os.File) { _ = file.Close() }(file) // 获取当前时间 location, _ := time.LoadLocation("Asia/Shanghai") now := time.Now().In(location).Format("2006/01/02 15:04:05.999999") // 写入文件 writer := bufio.NewWriter(file) _, _ = writer.WriteString(fmt.Sprintf("[error] %+v %+v\n\n", now, err)) _ = writer.Flush() } func main() { result, err := func2(0) if err != nil { // 这里会打印一大段调用堆栈信息(具体可看最后) info := fmt.Sprintf("%+v", err) fmt.Println(info) // 将错误信息写入日志文件(也可以写入数据库) WriteErrorLog(err) } else { fmt.Printf("result = %+v \n", result) } } // ========== 调用堆栈信息·开始 ========== // // runtime error: integer divide by zero // main.func1.func1 // D:/go/demo/cmd/main.go:17 // runtime.gopanic // C:/Program Files (x86)/go/src/runtime/panic.go:890 // runtime.panicdivide // C:/Program Files (x86)/go/src/runtime/panic.go:239 // main.func1 // D:/go/demo/cmd/main.go:22 // main.func2 // D:/go/demo/cmd/main.go:28 // main.main // D:/go/demo/cmd/main.go:66 // runtime.main // C:/Program Files (x86)/go/src/runtime/proc.go:250 // runtime.goexit // C:/Program Files (x86)/go/src/runtime/asm_amd64.s:1598 // main.func2 // D:/go/demo/cmd/main.go:32 // main.main // D:/go/demo/cmd/main.go:66 // runtime.main // C:/Program Files (x86)/go/src/runtime/proc.go:250 // runtime.goexit // C:/Program Files (x86)/go/src/runtime/asm_amd64.s:1598 // ========== 调用堆栈信息·结束 ========== // // ========== 总结 ========== // // 1、使用github.com/pkg/errors包可以获取错误的调用堆栈信息,利用这些信息可以很快定位错误方便debug。
Copyright © 2024 码农人生. All Rights Reserved