英文:
Getting the Actual Error Source in Go with Uber/Zap Logging in gRPC Middleware
问题
我正在使用uber/zap包进行日志记录。
在我的设计中,我在grpc包的中间件中记录任何错误。
我想记录错误来自哪个文件和行号。
然而,目前我只能获取当前中间件的文件名和行号。
有没有办法获取实际错误的源代码?
func RegisterLogger(c config.Config) *zap.SugaredLogger {
var logger *zap.Logger
var err error
if c.IsDebug {
logger, err = zap.NewDevelopment()
} else {
logger, err = zap.NewProduction()
}
if err != nil {
panic(err)
}
defer logger.Sync()
return logger.Sugar()
}
func (s *ProviderServer) Pay(ctx context.Context, in *payment.PayRequest) (string, error) {
resp, err := ctx.Value(in.Provider).(provider.IPayment).Exec(ctx, in)
if err != nil {
pc, file, line, ok := runtime.Caller(2)
if ok {
file = filepath.Base(file)
nowTime := time.Now().Format("2006/01/02 15:04:05")
funcName := runtime.FuncForPC(pc).Name()
funcName = filepath.Ext(funcName)
funcName = strings.TrimPrefix(funcName, ".")
s.log.Info("Times:", i, " nowTime:", nowTime, " file:", file, " line:", line, " funcName:", funcName, " err:", err)
}
//记录错误信息,包括错误来自哪个文件。
return resp.Result, err
} else {
s.log.Info("resp:", resp)
}
}
英文:
I am using the uber/zap package for logging.
In my design, I log any errors in the middleware of the grpc package.
I want to record which file and line number the error comes from.
However, currently, I can only get the filename and line number of the current middleware.
Is there any way to get the actual source of the error?
func RegisterLogger(c config.Config) *zap.SugaredLogger {
var logger *zap.Logger
var err error
if c.IsDebug {
logger, err = zap.NewDevelopment()
} else {
logger, err = zap.NewProduction()
}
if err != nil {
panic(err)
}
defer logger.Sync()
return logger.Sugar()
}
func (s *ProviderServer) Pay(ctx context.Context, in *payment.PayRequest) (string, error) {
resp, err := ctx.Value(in.Provider).(provider.IPayment).Exec(ctx, in)
if err != nil {
pc, file, line, ok := runtime.Caller(2)
if ok {
file = filepath.Base(file)
nowTime := time.Now().Format("2006/01/02 15:04:05")
funcName := runtime.FuncForPC(pc).Name()
funcName = filepath.Ext(funcName)
funcName = strings.TrimPrefix(funcName, ".")
s.log.Info("Times:", i, " nowTime:", nowTime, " file:", file, " line:", line, " funcName:", funcName, " err:", err)
}
//Log the error information, including which file the error comes from.
return resp.Result, err
} else {
s.log.Info("resp:", resp)
}
}
答案1
得分: 0
在你当前的实现中,你试图记录错误发生的文件和行号。然而,你得到的信息是当前中间件的信息,而不是错误的实际源头。
为了获取实际错误源头的文件和行号信息,你可以使用pkg/errors
包。该包提供了一种包装错误并保留文件和行号信息的方法。下面是一个修改你的代码以实现这一点的示例:
import (
"github.com/pkg/errors"
)
// ...
func (s *ProviderServer) Pay(ctx context.Context, in *payment.PayRequest) (string, error) {
resp, err := ctx.Value(in.Provider).(provider.IPayment).Exec(ctx, in)
if err != nil {
// 使用文件和行号信息包装错误
err = errors.Wrap(err, "pay error")
// 记录包装后的错误
s.log.Errorw("Error occurred", "error", err)
return resp.Result, err
} else {
s.log.Infow("Request processed successfully", "response", resp)
return resp.Result, nil
}
}
通过使用errors.Wrap
函数包装错误,你可以将文件和行号信息添加到错误中。然后,当使用s.log.Errorw
记录错误时,日志消息将包含完整的堆栈跟踪,包括错误发生的文件和行号信息。
这样,你就可以使用errors
包提供的信息追踪错误的实际源头。
英文:
In your current implementation, you are trying to log the file and line number where an error occurs. However, the information you are getting is for the current middleware, not the actual source of the error.
To get the file and line information of the actual source of the error, you can make use of the pkg/errors
package. This package provides a way to wrap errors and preserve the file and line information. Here's an example of how you can modify your code to achieve this:
import (
"github.com/pkg/errors"
)
// ...
func (s *ProviderServer) Pay(ctx context.Context, in *payment.PayRequest) (string, error) {
resp, err := ctx.Value(in.Provider).(provider.IPayment).Exec(ctx, in)
if err != nil {
// Wrap the error with file and line information
err = errors.Wrap(err, "pay error")
// Log the wrapped error
s.log.Errorw("Error occurred", "error", err)
return resp.Result, err
} else {
s.log.Infow("Request processed successfully", "response", resp)
return resp.Result, nil
}
}
By wrapping the error with the errors.Wrap
function, you add the file and line information to the error. Then, when logging the error using s.log.Errorw
, the log message will contain the complete stack trace including the file and line information where the error originated.
This way, you can trace the actual source of the error using the information provided by the errors
package.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论