Go 1.17:如何记录带有堆栈跟踪的错误

huangapple go评论93阅读模式
英文:

Go 1.17: How to log error with the stack trace

问题

如何记录错误的行号和文件名?我尝试过使用%w、zap logger的Errorw,但它们的效果不如github.com/pkg/errors好,而该库已经被存档了。以下是代码示例:

package main

import (
	stderrors "errors"

	pkgerrors "github.com/pkg/errors"

	"go.uber.org/zap"
)

func main() {
	logger := zap.NewExample().Sugar()

	logger.Errorf("Hello %v %w", "error", stderrors.New("some error"))
	logger.Errorw("Hello", "error", stderrors.New("some error"))

	logger.Errorf("Hello %v %w", "error", pkgerrors.New("some error"))
	logger.Errorw("Hello", "error", pkgerrors.New("some error"))
}

这是相同代码的playground链接:https://go.dev/play/p/PO3dFrK5ua6

英文:

How to log the line number and file name of the error? I tried %w, zap logger's Errorw, but its not working as good as github.com/pkg/errors, which is sadly archived. Here is the code:

package main

import (
	stderrors "errors"

	pkgerrors "github.com/pkg/errors"

	"go.uber.org/zap"
)

func main() {
	logger := zap.NewExample().Sugar()

	logger.Errorf("Hello %v %w", "error", stderrors.New("some error"))
	logger.Errorw("Hello", "error", stderrors.New("some error"))

	logger.Errorf("Hello %v %w", "error", pkgerrors.New("some error"))
	logger.Errorw("Hello", "error", pkgerrors.New("some error"))
}

Here is the playgroud code for the same: https://go.dev/play/p/PO3dFrK5ua6

答案1

得分: 1

直接回答你的问题:https://www.bugsnag.com/blog/go-errors

但是我想说,在Go语言中这样做并不是一个好的实践。最好的做法是将错误传递到函数调用链中,并在之后打印出来。

func HandleApiReq() (*APIResponse, error) {
    // ...逻辑...错误处理
    gwres, err := QueryGateway()
    // ...逻辑...错误处理
    return nil, fmt.Errorf("在端点 %s 处处理 API 请求失败:%v", endpoint, err)
}

func QueryGateway() (*GatewayResult, error) {
    // ...逻辑...错误处理
    dbres, err := GetFromDB()
    // ...逻辑...错误处理
    return nil, fmt.Errorf("在网关 %s 中从数据库接收到错误:%v", gw.Name(), err)
}

func GetFromDb() (*DBResult, error) {
    // ...逻辑...错误处理
    return nil, fmt.Errorf("从数据库获取失败。在表 %s 上接收到数据库错误:%v", tableName, err)
}

因此,假设你的数据库出现错误,最终的输出将自然地由之前的所有错误构建而成,如下所示:
在端点 /products 处处理 API 请求失败:在网关 stock_gateway 中从数据库接收到错误:从数据库获取失败。在表 products 上接收到数据库错误:发生死锁

英文:

To directly answer your question: https://www.bugsnag.com/blog/go-errors

But I want to just say that it's not good practice to do this in Go. It's best to float your errors down the function calls and print them out after.

func HandleApiReq() (*APIResponse, error) {
    // ...logic...error handling
    gwres, err := QueryGateway()
    // ...logic...error handling
    return nil, fmt.Errorf("failed to process API request on endpoint %s: %v", endpoint, err)
}

func QueryGateway() (*GatewayResult, error) {
    // ...logic...error handling
    dbres, err := GetFromDB()
    // ...logic...error handling
    return nil, fmt.Errorf("error received from db in gateway %s: %v", gw.Name(), err)
}

func GetFromDb() (*DBResult, error) {
    // ...logic...error handling
    return nil, fmt.Errorf("failed to get from db. Db err received on table %s: %v", tableName err)
}

So your end output assuming your db gets an error will naturally be built from all your previous errors like:
failed to process API request on endpoint /products: error received from db in gateway stock_gateway: failed to get from db. Db err received on table name products: Deadlock occurred

答案2

得分: 1

你可以像这样使用:

log.New(os.Stdout, "ERROR\t", log.Ldate|log.Ltime|log.Lshortfile)
英文:

you can use like this,

log.New(os.Stdout, "ERROR\t", log.Ldate|log.Ltime|log.Lshortfile)

huangapple
  • 本文由 发表于 2022年4月29日 14:35:38
  • 转载请务必保留本文链接:https://go.coder-hub.com/72053708.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定