在 Debian 上运行 Golang 程序时,“日志切割”通常有两种常见做法,取决于你日志是写到 stdout 还是文件。
下面按最常见、最推荐的方式给你讲清楚。
✅ 生产环境最佳实践
Golang 只管写日志(stdout 或文件),切割由 Debian 的 logrotate 完成
package main
import (
"log"
"os"
)
func main() {
f, err := os.OpenFile("/var/log/myapp/app.log",
os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0644)
if err != nil {
panic(err)
}
defer f.Close()
log.SetOutput(f)
for {
log.Println("hello, golang log")
time.Sleep(5 * time.Second)
}
}
sudo apt install logrotate
sudo vim /etc/logrotate.d/myapp
内容示例:
/var/log/myapp/app.log {
daily
rotate 7
missingok
notifempty
compress
delaycompress
copytruncate
dateext
}
解释:
| 参数 | 作用 |
|---|---|
| daily | 每天切割 |
| rotate 7 | 保留 7 份 |
| compress | 压缩旧日志 |
| copytruncate | 不重启程序,直接截断文件 |
| dateext | 按日期命名 |
✅ copytruncate 对 Golang 非常重要
否则你可能会遇到“日志还在写旧文件”的问题。
sudo logrotate -vf /etc/logrotate.d/myapp
如果你用 systemd 管理服务(Debian 默认支持)
log.Println("hello")
不写文件,直接打 stdout。
[Unit]
Description=My Go App
[Service]
ExecStart=/usr/local/bin/myapp
Restart=always
StandardOutput=append:/var/log/myapp/app.log
StandardError=append:/var/log/myapp/error.log
[Install]
WantedBy=multi-user.target
然后仍然用 logrotate 切割 /var/log/myapp/app.log
✅ 这是云原生 / Docker / Kubernetes 推荐方式
go get gopkg.in/natefinch/lumberjack.v2
import (
"log"
"gopkg.in/natefinch/lumberjack.v2"
)
func main() {
log.SetOutput(&lumberjack.Logger{
Filename: "/var/log/myapp/app.log",
MaxSize: 100, // MB
MaxBackups: 7,
MaxAge: 30, // days
Compress: true,
})
log.Println("golang log with rotation")
}
✅ 优点:简单
❌ 缺点:
| 场景 | 推荐方案 |
|---|---|
| Debian 物理机 / 云服务器 | ✅ logrotate |
| systemd 管理服务 | ✅ stdout + logrotate |
| 容器 / K8s | ✅ stdout |
| 小工具 / 单机 | lumberjack |
✅ 用 copytruncate
sudo chown -R appuser:appuser /var/log/myapp
sudo systemctl restart logrotate.timer
✅ Debian 上 Golang 日志切割:Golang 写日志,logrotate 切日志
如果你愿意,我可以: