重定向stderr记录go进程崩溃日志

go语言实现的进程在遇到panic、非法内存访问、未加锁的并发访问等情况时会崩溃并将stack backtrace输出到stderr。可通过重定向stderr将崩溃信息记录下来,便于后续排查问题。
最近游戏服发生了一次崩溃,我通过该方法修改了代码。部署当时就发现了一个代码缺陷,有一行代码有时引用空指针。第二天又收集到一次崩溃信息,文件最开始显示“fatal error: concurrent map iteration and map write”,后面还记录了代码中问题出现的位置。然后我按图索骥,很快修复了问题。
重定向stderr到文件的代码如下:

package main

import (
    "os"
    "fmt"
    "time"
    "syscall"
    ...
)

func main() {
    const dir = `./fatal`
    if err := os.MkdirAll(dir, 0700); err != nil {
        panic(err)
    }
    t := time.Now()
    ts := fmt.Sprintf("%d-%02d-%02dT%02d-%02d-%02d",
        t.Year(), t.Month(), t.Day(),
        t.Hour(), t.Minute(), t.Second())
    f, err := os.OpenFile(dir+"/a-"+ts+".log", os.O_CREATE|os.O_APPEND|os.O_WRONLY, 0600)
    if err != nil {
        panic(err)
    }
    defer f.Close()
    syscall.Dup2(int(f.Fd()), int(os.Stderr.Fd())) // 将 stderr 重定向到 f
    ...
}

...

文件中记录的stack backtrace重点内容如下:

fatal error: concurrent map iteration and map write

goroutine 209561918 [running]:
runtime.throw(0x1a113da, 0x26)
        /usr/local/Cellar/go/1.14.3/libexec/src/runtime/panic.go:1116 +0x72 fp=0xc80c5617c8 sp=0xc80c561798 pc=0xa34982
runtime.mapiternext(0xc80c561880)
        /usr/local/Cellar/go/1.14.3/libexec/src/runtime/map.go:853 +0x552 fp=0xc80c561848 sp=0xc80c5617c8 pc=0xa10562
... 后面是出问题的业务代码的文件名和行数

你可能感兴趣的:(重定向stderr记录go进程崩溃日志)