在 CentOS 上让 Golang 程序的日志进行轮转(log rotation),常见有 三种做法,从“最推荐”到“最原生”给你讲清楚。
思路:
Golang 只负责写日志文件(如 /var/log/myapp.log),轮转交给 CentOS 的 logrotate。
package main
import (
"log"
"os"
)
func main() {
f, _ := os.OpenFile("/var/log/myapp.log",
os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0644)
defer f.Close()
log.SetOutput(f)
for {
log.Println("running...")
time.Sleep(time.Second)
}
}
⚠️ 关键点:
O_APPEND新建配置文件:
sudo vim /etc/logrotate.d/myapp
内容示例:
/var/log/myapp.log {
daily
rotate 7
missingok
notifempty
compress
delaycompress
copytruncate
}
常用参数说明:
daily:每天轮转rotate 7:保留 7 份compress:压缩旧日志copytruncate:不关闭文件直接截断(适合 Golang)✅ copytruncate 是 Golang 最省心方案
sudo logrotate -f /etc/logrotate.d/myapp
适合 容器 / 无 logrotate 环境
gopkg.in/natefinch/lumberjack.v2(最流行)import (
"log"
"gopkg.in/natefinch/lumberjack.v2"
)
func main() {
log.SetOutput(&lumberjack.Logger{
Filename: "/var/log/myapp.log",
MaxSize: 10, // MB
MaxBackups: 5,
MaxAge: 7, // days
Compress: true,
})
log.Println("hello")
}
✅ 优点:
❌ 缺点:
如果你用 systemd 管理 Golang 服务:
sudo vim /etc/systemd/system/myapp.service
[Unit]
Description=myapp
[Service]
ExecStart=/opt/myapp/myapp
Restart=always
[Install]
WantedBy=multi-user.target
然后仍然用 logrotate + copytruncate
| 场景 | 推荐方案 |
|---|---|
| CentOS 服务器 | ✅ logrotate + copytruncate |
| Docker / K8s | ✅ 标准输出 + 容器日志 |
| 单进程小工具 | ✅ lumberjack |
| 多进程 | ❌ 不建议自己切 |
如果你愿意,我可以:
你现在是 裸 Go / 框架 / 容器 哪种?