You can programmatically catch some problems and process a panic log for them. But this will not work, for example. OOM errors or deadlocks.
A limited case can be illustrated, 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) }
Playground
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 during any process failure, including OOM and deadlocks, ...: redirect your stderr to any location (e.g. pipe, file).
source share