有没有什么有效的方法可以轻松地在Unix下获取Go程序的恐慌记录?

时间:2013-05-09 11:33:02

标签: linux unix logging go panic

由于我正在运行Go程序作为服务器,我需要一些机制来捕获恐慌日志,如果出现任何问题,以便以后进行分析&调试。有没有什么有效的方法可以轻松地在Unix下获取Go程序的恐慌记录?你们能介绍一下你的经历吗?谢谢:))

2 个答案:

答案 0 :(得分:7)

我在手机上收到一些通知,告诉我一些致命的恐慌。方法如下:

首先,我通常会在daemontools(或类似)下运行所有​​内容,以便对其进行监控,并在失败时自行重启。

然后,我通常使用内置日志包登录到syslog。我的系统日志转发到papertrail,在那里我可以查看事物的状态,设置警报等等......我在这里将不受欢迎的事件通知转发到电子邮件地址和notifymyandroid,这样我就可以了解问题,寻找类似的近期问题,查看问题的背景等等......

...但是你无法记录你自己未被捕获的致命恐慌,所以我写了logexec来执行程序并分别记录它的stdout和stderr以及不成功的退出通知。

示例:

logexec -tag myprogram /path/to/myprogram -and -its arguments

答案 1 :(得分:3)

可以通过编程方式捕获一些问题,并为它们处理恐慌日志。但它不适用于例如。 OOM错误或死锁。

有限的情况可以说明,例如:

package main

import (
        "fmt"
        "os"
        "runtime"
)

func fact(n int) int {
        if 1/n == 42 {
                return 314
        }

        return n * fact(n-1)
}

func main() {
        const maxTrace = 1000
        defer func() {
                if e := recover(); e != nil {
                        fmt.Fprintf(os.Stderr, "Panic log, recovered: '%v'", e)
                        var b [maxTrace]byte
                        fmt.Fprintf(os.Stderr, "%s", b[:runtime.Stack(b[:], true)])
                }
        }()

        fact(3)
}

Playground


输出:

Panic log, recovered: 'runtime error: integer divide by zero'goroutine 1 [running]:
main.func·001()
        /tmpfs/gosandbox-9ec179e4_f9a94b22_357f29a2_2f5f25c4_b484febf/prog.go:23 +0x14b
main.fact(0x0, 0x4103f1)
        /tmpfs/gosandbox-9ec179e4_f9a94b22_357f29a2_2f5f25c4_b484febf/prog.go:10 +0x2b
main.fact(0x1, 0x0)
        /tmpfs/gosandbox-9ec179e4_f9a94b22_357f29a2_2f5f25c4_b484febf/prog.go:14 +0x54
main.fact(0x2, 0x0)
        /tmpfs/gosandbox-9ec179e4_f9a94b22_357f29a2_2f5f25c4_b484febf/prog.go:14 +0x54
main.fact(0x3, 0x401005)
        /tmpfs/gosandbox-9ec179e4_f9a94b22_357f29a2_2f5f25c4_b484febf/prog.go:14 +0x54
main.main()
        /tmpfs/gosandbox-9ec179e4_f9a94b22_357f29a2_2f5f25c4_b484febf/prog.go:27 +0x37

要捕获所有进程崩溃的所有 goroutines的堆栈跟踪,包括OOM和死锁,......:将其stderr重定向到任何所需位置(例如。pipe,file)。