在 CentOS 上运行 Golang 程序时,“日志写满(磁盘满 / 日志爆满)”是很常见的问题,通常不是 Golang 本身的 bug,而是日志配置或使用方式不当导致的。下面按「常见原因 → 排查方法 → 解决建议」给你系统说明。
很多 Golang 程序直接用:
log.Println(...)
fmt.Println(...)
输出到 stdout 或文件,但没有 log rotate。
在 CentOS 上常见场景:
nohup ./app > app.log &结果:
✅ 典型现象:
df -h
/dev/sda1 100% /var
生产环境还开着:
log.SetLevel(log.DebugLevel)
结果:
✅ 检查:
grep -R "DebugLevel\|logger.Debug" .
典型代码问题:
for {
log.Println("error")
}
或:
defer func() {
if err != nil {
log.Println(err)
}
}()
在 panic recover 场景里反复触发。
✅ 特征:
CentOS 7/8 使用 journald:
查看:
journalctl -u your-service
du -sh /var/log/journal
如果你是容器运行:
log-opt max-sizedocker inspect <container> | grep Log
zap / logrusdf -h
du -sh /var/log/*
find / -type f -size +100M 2>/dev/null
watch -n 1 'ls -lh app.log'
lsof | grep deleted
iotop
推荐:
示例(zap):
logger, _ := zap.NewProduction()
defer logger.Sync()
logger.Info("start")
import "gopkg.in/natefinch/lumberjack.v2"
log.SetOutput(&lumberjack.Logger{
Filename: "/var/log/app.log",
MaxSize: 100,
MaxBackups: 5,
MaxAge: 7,
Compress: true,
})
/etc/logrotate.d/app
/var/log/app.log {
daily
rotate 7
compress
missingok
notifempty
copytruncate
}
测试:
logrotate -d /etc/logrotate.d/app
[Service]
StandardOutput=journal
journalctl --vacuum-size=500M
{
"log-driver": "json-file",
"log-opts": {
"max-size": "100m",
"max-file": "5"
}
}
✅ 不写 stdout 到文件
✅ 用 zap + lumberjack
✅ 生产只开 info/warn
✅ 容器必须限日志
✅ 定期 logrotate
如果你愿意,可以把:
df -h 结果发出来,我可以直接帮你精确定位是哪一类问题。