是否可以修改Golang堆栈跟踪?

时间:2018-03-02 01:47:08

标签: go

我正在将应用部署到云服务提供商,而日志只能逐行提取。我希望能够将堆栈转储中的换行符替换为其他字符,这样我就可以将堆栈跟踪保持在一起。

是否有可能做任何事情来操作程序失败时转储的堆栈跟踪?

1 个答案:

答案 0 :(得分:0)

您可以在恢复恐慌的功能中运行所有内容,然后在恢复的任何恐慌中执行您想要的操作:

func main() {
    defer func() {
        if r := recover(); r != nil {
            // Log whatever/however you want
            os.Exit(1) // to terminate the program
        }
    }()
    // the rest of your code here
}

请注意,这有局限性。它不会发现在main()之外发生的任何恐慌,在某些程序中,它几乎就是一切。特别是,它不会引起恐慌:

  • go routines
  • init()函数
  • 隐式初始化代码,即全局`var x = / *某些可能恐慌的函数* /``

对于这些情况,可以在每个关键点使用(并调用)更一般的恐慌处理程序。即。

func handlePanic() {
    if r := recover(); r != nil {
        // Do your logging
        os.Exit(1)
    }
}

// then later ...
func init() {
    defer handlePanic()
    // do stuff
}

// or ...
go func() {
    defer handlePanic()
    // do things that may panic
}()

在任何这些情况下,您都将被迫进行自己的堆栈跟踪处理。使用runtime.Caller或类似物来构建堆栈跟踪,然后创建所需的输出。请注意,堆栈跟踪与您之前看到的不同,因为它现在是在代码的不同部分创建的。通过跳帧或在其他地方记录堆栈跟踪等获得理想的堆栈跟踪,可以留给读者。