英文:
Is there any efficient way to get panic log of Go program under Unix easily?
问题
由于我正在运行一个作为服务器的Go程序,如果出现任何问题,我需要一些机制来捕获panic日志以供以后分析和调试。在Unix下,有没有一种简便的方法来获取Go程序的panic日志?你们能介绍一下你们的经验吗?谢谢
英文:
Since I'm running a Go program as server, I need some mechanism to catch panic log if anything goes wrong for later analyze & debug. Is there any efficient way to get panic log of Go program under Unix easily? Can you guys introduce your experience about this? Thanks
答案1
得分: 7
我在手机上收到一些关于我的go程序致命恐慌的通知。这是如何做到的:
首先,我通常在daemontools(或类似的工具)下运行所有东西,这样它就会被监控,并在失败时重新启动。
然后,我通常使用内置的日志包将日志记录到syslog中。我的syslog会转发到papertrail,我可以在那里查看事物的状态,设置警报等等...在这里,我将不希望的事件通知转发到一个电子邮件地址和notifymyandroid,这样我就可以意识到问题,搜索类似的最近问题,查看问题周围的上下文等等...
...但是你不能记录自己的未捕获的致命恐慌,所以我编写了logexec来执行程序并将其stdout和stderr分别记录下来,同时发送一个执行失败的通知。
示例:
logexec -tag myprogram /path/to/myprogram -and -its arguments
英文:
I get a notification on my phone for some of my fatal panics on go programs. Here's how:
First, I generally run everything under daemontools (or similar) so it's monitored and will restart itself on failure.
Then, I generally log to syslog using the built-in log package. My syslog forwards to papertrail where I can review the state of things, set up alerts, etc... It is here I forward undesirable event notifications to an email address and notifymyandroid so I can be made aware of problems, search for similar recent issues, look at context around the problems, etc...
...but you can't log your own uncaught fatal panic, so I wrote logexec to execute the program and log its stdout and stderr separately along with an unsuccessful exit notification.
Example:
logexec -tag myprogram /path/to/myprogram -and -its arguments
答案2
得分: 3
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
英文:
It's possible to programmatically catch some troubles and process a panic log for them. But it'll not work for eg. OOM errors or deadlocks.
The limited case can be illustrated like, for example:
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)
}
Output:
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
To capture the stack trace for all goroutines on any kind of process crash, including OOM and deadlocks, ...: redirect its stderr to any desired place (eg. pipe, file).
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论