在 Linux 上用 Go 写程序时,“日志丢失”通常不是 Go 本身的问题,而是输出方式、进程管理、缓冲、文件轮转或权限等环境相关原因。下面按最常见原因逐一说明,并给出排查和解决办法。
很多 Go 程序直接用:
log.Println("xxx")
fmt.Println("xxx")
这写的是 stdout/stderr。
如果你是用:
./app
然后关掉终端,或后台运行:
./app &
日志可能:
✅ 解决:
./app > app.log 2>&1
例如:
w := bufio.NewWriter(f)
w.WriteString("log")
// 没调用 w.Flush()
或:
bufio.Writer✅ 解决:
defer w.Flush()log.SetOutput 直接写文件(无缓冲)log.Fatal 会调用 os.Exit,不执行 deferkill -9 直接杀进程✅ 解决:
defer func() {
if r := recover(); r != nil {
log.Println("panic:", r)
}
}()
例如:
app.log 改成 app.log.1tail 的是“新文件”✅ 表现:
ls 看不到文件lsof | grep deleted 能看到✅ 解决:
zerolog / zap + lumberjack&lumberjack.Logger{
Filename: "app.log",
MaxSize: 100,
MaxBackups: 3,
Compress: true,
}
f, _ := os.OpenFile("/var/log/app.log", ...)
log.SetOutput(f)
如果:
你可能完全不知道。
✅ 解决:
systemd 默认只保留一定量的 stdout。
✅ 解决:
StandardOutput=journal
StandardError=journal
journalctl -u your-service容器里:
✅ 解决:
标准 log 是并发安全的,但:
✅ 解决:
log(默认安全)如果你愿意,可以把:
发出来,我可以直接帮你定位是哪一类问题。