温馨提示×

centos golang日志为何丢失

小樊
38
2026-09-30 06:28:23
栏目: 编程语言

在 CentOS 上运行 Go 程序时“日志丢失”是一个比较常见的问题,通常不是 Go 本身丢日志,而是运行环境、重定向、systemd、buffer、权限等原因导致的。下面按常见原因逐一说明,并给出排查和解决办法。


一、最常见原因:systemd + stdout/stderr 日志“看不到”

现象

  • 用 log.Println / fmt.Println
  • 程序用 systemctl 启动
  • 日志没写文件,也没在 journalctl 里

原因

  • CentOS 7/8 默认用 systemd
  • Go 输出到 stdout/stderr
  • 但 journal 没开,或你没用 journalctl 看

解决

journalctl -u your-service -f

或 不要依赖 stdout,直接写日志文件:

log.SetOutput(os.OpenFile("/var/log/app.log", os.O_CREATE|os.O_APPEND|os.O_WRONLY, 0644))

二、日志被缓冲(Buffered),进程被杀导致丢失

现象

  • 程序突然被 kill
  • 最后几秒日志没了

原因

  • 自己实现的 logger 用了 bufio.Writer
  • 没调用 Flush()
  • 或 log 被包装成异步

解决

writer.Flush()

或在程序退出前:

defer writer.Flush()

✅ 推荐:使用 zap / logrus(自带 flush 或同步写)


三、日志文件被 logrotate 截断

现象

  • 日志突然“清空”
  • 或文件存在但大小为 0

原因

  • CentOS 默认 logrotate
  • Go 打开的是 旧文件 fd
  • rotate 后写到了已删除的文件

解决

  1. 使用 copytruncate
  2. 或发信号重新打开日志
  3. 或用 logrotate + 专业日志库

示例 logrotate:

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

四、权限问题导致日志写不进去

现象

  • 程序能跑
  • 日志文件没生成
  • 或写一半停止

原因

  • 用 systemd 以非 root 运行
  • /var/log 没权限

解决

mkdir /var/log/app
chown appuser:appuser /var/log/app

五、程序 panic / 提前退出

现象

  • 启动后日志直接断
  • 没有任何错误

原因

  • os.Exit()
  • panic 没 recover
  • init 阶段出错

解决

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

六、Docker / nohup / 重定向问题(CentOS 常见)

错误示例

./app > log.txt &
  • 终端关闭后可能丢
  • 或 buffer 不刷新

解决

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

或用 systemd(推荐)


七、SELinux 阻止写日志(CentOS 特有)

现象

  • 程序能跑
  • 日志写不进去
  • /var/log/audit/audit.log 有拒绝记录

解决

setenforce 0

或:

semanage fcontext -a -t var_log_t "/var/log/app(/.*)?"
restorecon -Rv /var/log/app

八、推荐的 CentOS Go 日志最佳实践 ✅

✅ 不要只用 fmt.Println
✅ 使用日志库(zap / logrus)
✅ 明确指定日志文件
✅ systemd 管理服务
✅ 配置 logrotate
✅ 程序退出前 flush


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

  • CentOS 版本(7 / 8 / Stream)
  • 启动方式(systemd / nohup / docker)
  • 用的什么 logger
  • 日志丢失的具体表现

我可以帮你精准定位是哪一类问题。

0 踩