温馨提示×

为何centos golang日志丢失

小樊
39
2026-10-03 03:53:26
栏目: 编程语言

在 CentOS 上运行 Golang 程序时“日志丢失”是一个比较常见的问题,通常不是 Go 本身丢日志,而是运行环境、输出方式或日志框架配置导致的。下面按常见原因给你系统性梳理一下。


一、 stdout / stderr 被吞掉(最常见)

1. 使用 nohup / & 但没重定向

nohup ./app &

如果你没有重定向输出:

nohup ./app > app.log 2>&1 &

那么日志可能:

  • 写到了 nohup.out(但你可能没看)
  • 被 shell 关闭时截断
  • system 重启后全丢

✅ 正确方式:

nohup ./app >> /var/log/app.log 2>&1 &

二、使用 systemd 但没看对日志位置

2. CentOS 7+ 默认用 systemd

如果你用:

systemctl start yourapp

Go 的 log.Println / fmt.Println 默认输出到 stdout/stderr,会被 journald 接走。

❌ 常见误区:

  • 以为日志在文件里
  • 实际在 journal

✅ 查看方式:

journalctl -u yourapp.service
journalctl -u yourapp.service -f

✅ 如果想写文件:

[Service]
StandardOutput=append:/var/log/app.log
StandardError=append:/var/log/app.err

三、日志没 flush(缓冲问题)

3. 用了带 buffer 的 logger

例如:

  • bufio.Writer
  • 自写日志库
  • 某些第三方 logger 默认异步

进程被 kill -9 或 panic 时:

  • buffer 没 flush
  • 日志“丢失”

✅ 解决:

  • 使用 log.SetOutput(os.Stdout)(无缓冲)
  • 或定期 Flush()
  • 或直接使用 zap / slog

四、日志被 logrotate 截断

4. CentOS 默认 logrotate

如果:

  • 日志写文件
  • 没用 copytruncate
  • 或程序还持有旧 fd

结果:

  • 文件被移走
  • 程序还在写旧 inode
  • 你看新文件是空的

✅ 正确 logrotate 配置:

/var/log/app.log {
    daily
    rotate 7
    copytruncate
    missingok
}

五、权限问题导致写不进去

5. CentOS 权限严格

  • /var/log 非 root 不可写
  • SELinux 可能拦截

✅ 检查:

ls -Z /var/log/
getenforce

✅ 解决:

  • 放 /opt/app/log
  • 或改 SELinux 策略

六、Go 程序本身“崩得太快”

6. init / main 之前 panic

例如:

  • 配置文件缺失
  • 环境变量为空

这时:

  • 日志还没初始化
  • 你以为“没日志”

✅ 建议:

  • 最早就初始化 logger
  • 用 defer recovery + Fatal

七、容器 / Cron 场景

7. cron 环境没有 tty

* * * * * /opt/app

cron 的 stdout 默认发邮件,不写文件。

✅ 必须:

* * * * * /opt/app >> /var/log/app.log 2>&1

八、推荐做法(避免踩坑)

✅ 生产环境建议:

  • 用 zap 或 slog
  • 日志写文件 + systemd
  • 配 logrotate
  • 不依赖 stdout 持久化

如果你愿意,可以告诉我:

  • CentOS 版本
  • 怎么启动的(systemd / nohup / docker)
  • 用的什么日志库

我可以直接帮你定位是哪一种。

0 踩