golang 打印error的堆棧信息操作
眾所周知,目前的golang error只關(guān)注Error()信息,而不關(guān)注它的堆棧路徑,對錯誤的定位大多數(shù)通過
log.SetFlags(log.Llongfile| log.LstdFlags) log.Println(e)
一旦代碼分層,為了定位錯誤,可能出現(xiàn)每一個層次的同一個error,都得log好幾次,比如:
func DB()error{ return errors.New("time out") } func Dao()error{ if er:= DB();er!=nil{ log.Println(er) return error } return nil } func Service()error{ if er:= Dao();er!=nil{ log.Println(er) return error } return nil } func Control()error{ if er:= Service();er!=nil{ log.Println(er) return error } return nil }
如何一次性拋出錯誤,把該錯誤的堆棧全部都拿住呢
以模擬一次請求-分發(fā)-服務(wù)-數(shù)據(jù)庫操作為例:
package main import ( "errors" "fmt" "github.com/fwhezfwhez/errorx" ) func main() { if e := Control(); e != nil { e.(errorx.Error).PrintStackTrace() // log.Println(e.(errorx.Error).StackTrace()) } else { Reply() } } // assume an engine to connect mysql func DB() error { return errors.New("connect to mysql time out") } // handle database operation func Dao() error { if er := DB(); er != nil { return errorx.New(er) } return nil } // handle logic service func Service() error { if er := Dao(); er != nil { return errorx.Wrap(er) } return nil } // handle request distribute from main func Control() error { if er := Service(); er != nil { return errorx.ReGen(er, errors.New("inner service error,please call admin for help")) } return nil } // reply a the request func Reply(){ fmt.Println("handle success") }
執(zhí)行結(jié)果:
StackTrace | CausedBy
G:/go_workspace/GOPATH/src/errorX/example/main.go: 26 | connect to mysql time out
G:/go_workspace/GOPATH/src/errorX/example/main.go: 34 | connect to mysql time out
G:/go_workspace/GOPATH/src/errorX/example/main.go: 42 | inner service error,please call admin for help
補(bǔ)充:golang 異常退出堆棧捕獲
利用golang自帶包 runtime/debug 異常時打印
DebugInfo.go
package main import ( "fmt" "os" "runtime/debug" "time" ) func TryE() { errs := recover() if errs == nil { return } exeName := os.Args[0] //獲取程序名稱 now := time.Now() //獲取當(dāng)前時間 pid := os.Getpid() //獲取進(jìn)程ID time_str := now.Format("20060102150405") //設(shè)定時間格式 fname := fmt.Sprintf("%s-%d-%s-dump.log", exeName, pid, time_str) //保存錯誤信息文件名:程序名-進(jìn)程ID-當(dāng)前時間(年月日時分秒) fmt.Println("dump to file ", fname) f, err := os.Create(fname) if err != nil { return } defer f.Close() f.WriteString(fmt.Sprintf("%v\r\n", errs)) //輸出panic信息 f.WriteString("========\r\n") f.WriteString(string(debug.Stack())) //輸出堆棧信息 }
測試異常捕獲 main.go
package main import ( "fmt" "time" ) func main() { defer TryE() fmt.Println(time.Now()) panic(-2) fmt.Println("panic restore now, continue.") }
查看堆??梢远ㄎ籱ain 里第11行拋出異常-2.
以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。如有錯誤或未考慮完全的地方,望不吝賜教。
相關(guān)文章
go高并發(fā)時append方法偶現(xiàn)錯誤解決分析
這篇文章主要為大家介紹了go高并發(fā)時append方法偶現(xiàn)錯誤解決分析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-10-10golang控制結(jié)構(gòu)select機(jī)制及使用示例詳解
這篇文章主要介紹了golang控制結(jié)構(gòu)select機(jī)制及使用示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-10-10