温馨提示×

为何debian golang日志丢

小樊
34
2026-10-04 04:51:21
栏目: 编程语言

“Debian 上 Golang 日志丢失”通常不是 Go 本身的问题,而是运行环境、输出方式或系统配置导致的。下面按常见原因逐一说明,并给出排查/解决建议。


一、日志写到 stdout/stderr,但被系统“吞了”

1. systemd 吞日志(最常见)

在 Debian 上用 systemd 跑 Go 程序时:

  • Go 默认日志输出到 stderr
  • systemd 有日志缓冲和轮转
  • 程序崩溃 / 被杀 / 重启时,缓冲区可能没刷

现象

  • 本地跑有日志
  • systemd 下看不到或只看到一部分

解决

# /etc/systemd/system/your.service
[Service]
StandardOutput=journal
StandardError=journal

查看日志:

journalctl -u your.service -f

或强制输出到文件:

StandardOutput=append:/var/log/your.log
StandardError=append:/var/log/your.log

二、日志没及时 flush(缓冲问题)

2. 使用了带缓冲的 logger

如果你用了:

  • bufio.Writer
  • log.SetOutput(bufio.NewWriter(...))
  • 第三方日志库但没 flush

程序异常退出时,缓冲没写盘。

解决

  • 用 log.Println 默认 logger(无缓冲)
  • 或定期 Flush()
  • 或捕获信号:
c := make(chan os.Signal, 1)
signal.Notify(c, syscall.SIGTERM)
<-c
logger.Sync() // zap

三、程序被 OOM / SIGKILL

3. 被内核或 systemd 杀掉

  • 内存超限
  • KillMode=process

特点

  • 日志戛然而止
  • 没有任何 exit 日志

排查

dmesg | grep -i kill
journalctl -u your.service | grep -i oom

四、日志文件被轮转 / 删除

4. logrotate 后文件被删

如果你自己写文件:

os.OpenFile("app.log", O_CREATE|O_WRONLY|O_APPEND)

logrotate 后:

  • 文件被 rename
  • 程序仍写旧 fd
  • 新日志“消失”

解决

  • 用 logrotate + copytruncate
  • 或用 SIGUSR1 重新打开日志
  • 或直接用 systemd journal

五、时区 / 权限问题(看起来像“丢了”)

5. 权限不足

  • /var/log 没写权限
  • 用非 root 跑

✅ 检查:

ls -l /var/log/your.log

六、Go 程序“静默退出”

6. main 提前 return

  • os.Exit(0) 不跑 defer
  • goroutine 中 panic 被吞

建议

defer func() {
    if r := recover(); r != nil {
        log.Println("panic:", r)
    }
}()

七、推荐做法(稳定不丢日志)

✅ 生产环境推荐组合

  • systemd + journal
  • 或
  • systemd + 文件日志 + logrotate
  • 日志库用 zap / slog
  • 程序退出前 Sync()

快速自检清单

  • [ ] 是否用 systemd?
  • [ ] 日志是否走 stdout?
  • [ ] 是否用了缓冲 writer?
  • [ ] 是否 OOM?
  • [ ] 是否 logrotate?
  • [ ] 是否没 flush / Sync?

如果你愿意,可以把:

  • 启动方式(systemd? nohup? docker?)
  • 日志代码片段
  • Debian 版本

发出来,我可以直接帮你定位是哪一类“丢日志”。

0 踩