【问题标题】:Splitting traceback stack into structure in go在go中将回溯堆栈拆分为结构
【发布时间】:2020-09-04 13:40:51
【问题描述】:

我正在寻找一种在 golang 中记录回溯堆栈的方法,但只有其中的一些行。正如我所看到的,可以通过将从 debug.Stack() 获得的结果拆分为一个结构切片来完成,然后可以轻松地对其进行解析。

这就是我现在通过调用“fmt.Println(string(debug.Stack()))”得到的结果:

goroutine 1 [running]:
runtime/debug.Stack(0xc0000c0050, 0x2, 0x0)
        /go/go1.15rc1/src/runtime/debug/stack.go:24 +0x9f
main.go_logger(0x4cc235, 0x11, 0x4ccf9d, 0x15, 0xc000090101)
        /go/src/ethernet_monitor/info.go:30 +0x290
main.temp(...)
        /go/src/ethernet_monitor/info.go:40
main.main()
        /go/src/ethernet_monitor/info.go:45 +0x52

这就是我希望它被拆分的方式,类似于 python 的 traceback.extract_stack() 结构:

fileName: /go/src/ethernet_monitor/info.go
function: main.main()
lineNumber: 45

所以问题是 - 它是否已经以某种方式实现了?我对编写自己的解析函数不是很有信心,因为我可能会错过一些特定的案例。

【问题讨论】:

    标签: go logging stack traceback


    【解决方案1】:

    您最好使用runtime.Callers 来获取单个项目,而不是尝试将堆栈解析为字节。

    这就是github.com/pkg/errors 在此处所做的:https://github.com/pkg/errors/blob/master/stack.go#L163:1。可以看到runtime.Callers已经可以跳过某些关卡了。

    从需要的uintptr 可以看出,这是相当低级的。但是,您应该没问题,只需复制 callers 函数和它所依赖的所有内容,并使用 StackTrace 函数来获得更有用的单个 Frames 堆栈:https://github.com/pkg/errors/blob/master/stack.go#L155

    然后可以增强框架以返回函数名称、文件、行号等。如何提取这些信息可以在 Frame 的不同私有函数中看到:https://github.com/pkg/errors/blob/master/stack.go#L23

    我在我们的本地错误包中做了同样的事情,以便能够调整堆栈的打印方式。这可以在FrameFormat 函数中进行调整。

    注意:也许不是最简单的解决方案,因为这会让您接触到一些低级的东西,但我更喜欢它随时解析已经打印的堆栈。

    【讨论】:

    • 为什么不推荐runtime.Callers + runtime.CallersFrames + 遍历它们呢?我的意思是,当所有必需的部分都在标准库中时,您似乎会推荐来自 3rd-party 包的东西。
    • 感谢两位的建议。尚未使用框架,因此将朝那个方向搜索。很抱歉没有给你的 cmets 投票,因为我还没有足够的分数 :)
    • 我建议看看pkg/errors Dave Cheney 是如何做到的,不建议使用pkg/errors。所需的一切都存在于标准库中。
    • gtristan,如果对您有帮助,您应该可以将我的答案标记为已接受的答案。
    猜你喜欢
    • 2015-05-17
    • 1970-01-01
    • 1970-01-01
    • 2016-02-25
    • 1970-01-01
    • 1970-01-01
    • 2015-07-02
    • 2013-10-20
    • 2018-07-02
    相关资源
    最近更新 更多