有时候 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 \n\tat %s:%d (Method %s)\nCause by: %s\n", 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 \n\tat %s:%d (Method %s)\nCause by: %s\n", 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:"
/**
* 用特定信息新创建一个 error
*/
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 \n\tat %s:%d", fmt.Sprintf(format, a...), f.Name(), line)
return errors.New(errMsg)
}
/**
* 用特定信息包装一个 error,使其包含代码堆栈信息
* 如果 err 为空则返回空
*/
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 \n\tat %s:%d\nCause by: %s", wrapMsg, f.Name(), line, err.Error())
wrapErr = errors.New(errMsg)
}
return wrapErr
}
/**
* 用特定信息包装一个 error,使其包含代码堆栈信息
* 如果 err 为空则返回空
*/
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 \n\tat %s:%d\nCause 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 \n\tat %s:%d\nCause 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 \n\tat %s:%d\nCause by: %s", preStr, f.Name(), line, err.Error())
}
return errMsg
}
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)