在 CentOS 上给 Golang 程序做日志切割,常见有 三种方案,从简单到生产级分别是:
lumberjack(最常用)这是 Go 生态里最主流的日志切割方案,常配合 logrus / zap / slog。
go get gopkg.in/natefinch/lumberjack.v2
import (
"go.uber.org/zap"
"go.uber.org/zap/zapcore"
"gopkg.in/natefinch/lumberjack.v2"
)
func main() {
w := zapcore.AddSync(&lumberjack.Logger{
Filename: "/var/log/myapp/app.log",
MaxSize: 100, // MB
MaxBackups: 10,
MaxAge: 30, // days
Compress: true,
})
core := zapcore.NewCore(
zapcore.NewJSONEncoder(zap.NewProductionEncoderConfig()),
w,
zap.InfoLevel,
)
logger := zap.New(core)
defer logger.Sync()
logger.Info("hello world")
}
✅ 优点
logrotate适合 直接写文件 的 Go 程序(如 log.Println)
log.SetOutput(os.OpenFile("/var/log/myapp/app.log", os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644))
sudo vim /etc/logrotate.d/myapp
内容示例:
/var/log/myapp/*.log {
daily
rotate 15
compress
delaycompress
missingok
notifempty
copytruncate
}
⚠️ 关键参数说明
copytruncate:不重启进程直接截断日志(Go 程序必须加)daily:按天compress:压缩旧日志sudo logrotate -d /etc/logrotate.d/myapp
sudo logrotate -f /etc/logrotate.d/myapp
✅ 优点
❌ 缺点
copytruncate如果你用 systemd 启动 Go 程序:
sudo vim /etc/systemd/system/myapp.service
[Service]
StandardOutput=journal
StandardError=journal
查看日志:
journalctl -u myapp -f
可配合:
journalctl --vacuum-size=500M
✅ 适合容器 / 云环境
❌ 不适合需要长期落盘分析的场景
| 方案 | 是否改代码 | 精确度 | 推荐场景 |
|---|---|---|---|
| lumberjack | ✅ | 高 | 生产环境首选 |
| logrotate | ❌ | 中 | 老项目 / 简单服务 |
| journald | ❌ | 低 | 容器 / systemd |
✅ Golang + zap + lumberjack + 不大依赖 logrotate
如果你的程序是直接 fmt/log 输出,就用 logrotate + copytruncate
如果你愿意,可以告诉我:
我可以直接给你 完整可运行配置。