有时候 golang 打印了错误日志,却发现很多地方都有打印这种日志,定位起来有点难度,有没有一些方法,在打印错误日志的时候把代码堆栈也打印出来呢?
方法如下:
func WrapError(wrapMsg string, err error) error {
pc, file, line, ok := runtime.Caller(1)
f := runtime.FuncForPC(pc)
if !ok {
return errors.New("WrapError 方法获取堆栈失败")
}
if err == nil {
return nil
} else {
errMsg := fmt.Sprintf("%s ntat %s:%d (Method %s)nCause by: %sn", wrapMsg, file, line, f.Name(), err.Error())
return errors.New(errMsg)
}
}
func GetErrorStack(preStr string, err error) string {
pc, file, line, ok := runtime.Caller(1)
f := runtime.FuncForPC(pc)
if !ok {
return "GetErrorStack 方法获取堆栈失败,返回错误原信息:" + err.Error()
}
if err == nil {
return ""
} else {
errMsg := fmt.Sprintf("%s ntat %s:%d (Method %s)nCause by: %sn", preStr, file, line, f.Name(), err.Error())
return errMsg
}
}
测试方法如下:
func TestWrapError(t *testing.T) {
err := errors.New("you are wrong")
err = WrapError("oneWrap", err)
err = WrapError("twoWrap", err)
fmt.Print(err)
}
func TestGetErrorStack(t *testing.T) {
err := errors.New("I am an error")
fmt.Println(GetErrorStack("real an error", err))
}
结果:
新增了些方法,优化显示:
package error_util
import (
"errors"
"fmt"
"runtime"
)
const defaultErrMsg = "Error occur:"
func NewErrorf(format string, a ...interface{}) error {
pc, _, line, ok := runtime.Caller(1)
f := runtime.FuncForPC(pc)
if !ok {
return errors.New("WrapError 方法获取堆栈失败")
}
errMsg := fmt.Sprintf("error occur, cause: %s ntat %s:%d", fmt.Sprintf(format, a...), f.Name(), line)
return errors.New(errMsg)
}
func WrapError(err error, wrapMsg string) error {
pc, _, line, ok := runtime.Caller(1)
f := runtime.FuncForPC(pc)
if !ok {
return errors.New("WrapError 方法获取堆栈失败")
}
var wrapErr error = nil
if err != nil {
if wrapMsg == "" {
wrapMsg = defaultErrMsg
}
errMsg := fmt.Sprintf("%s ntat %s:%dnCause by: %s", wrapMsg, f.Name(), line, err.Error())
wrapErr = errors.New(errMsg)
}
return wrapErr
}
func WrapErrorf(err error, wrapMsgFmt string, a ...interface{}) error {
wrapMsg := ""
if wrapMsgFmt == "" {
wrapMsg = defaultErrMsg
} else {
wrapMsg = fmt.Sprintf(wrapMsgFmt, a...)
}
pc, _, line, ok := runtime.Caller(1)
f := runtime.FuncForPC(pc)
if !ok {
return errors.New("WrapError 方法获取堆栈失败")
}
var wrapErr error = nil
if err != nil {
if wrapMsg == "" {
wrapMsg = defaultErrMsg
}
errMsg := fmt.Sprintf("%s ntat %s:%dnCause by: %s", wrapMsg, f.Name(), line, err.Error())
wrapErr = errors.New(errMsg)
}
return wrapErr
}
func GetErrorStack(err error, preStr string) string {
pc, _, line, ok := runtime.Caller(1)
f := runtime.FuncForPC(pc)
if !ok {
return "GetErrorStack 方法获取堆栈失败,返回错误原信息:" + err.Error()
}
var errMsg string
if err != nil{
if preStr == "" {
preStr = defaultErrMsg
}
errMsg = fmt.Sprintf("%s ntat %s:%dnCause by: %s", preStr, f.Name(), line, err.Error())
}
return errMsg
}
func GetErrorStackf(err error, preStrFmt string, a ...interface{}) string {
preStr := ""
if preStrFmt == "" {
preStr = defaultErrMsg
} else {
preStr = fmt.Sprintf(preStrFmt, a...)
}
pc, _, line, ok := runtime.Caller(1)
f := runtime.FuncForPC(pc)
if !ok {
return "GetErrorStack 方法获取堆栈失败,返回错误原信息:" + err.Error()
}
var errMsg string
if err != nil{
if preStr == "" {
preStr = defaultErrMsg
}
errMsg = fmt.Sprintf("%s ntat %s:%dnCause by: %s", preStr, f.Name(), line, err.Error())
}
return errMsg
}



