在 Go 里做日志切割(log rotation),常见做法有三种,从“最推荐”到“最原始”依次说明,并给出可直接用的示例。
lumberjack(生产级)这是 Go 里最主流、最成熟的日志切割方案,被 logrus、zap 等广泛使用。
go get gopkg.in/natefinch/lumberjack.v2
package main
import (
"log"
"gopkg.in/natefinch/lumberjack.v2"
)
func main() {
log.SetOutput(&lumberjack.Logger{
Filename: "logs/app.log",
MaxSize: 10, // MB
MaxBackups: 7, // 保留旧文件数
MaxAge: 30, // 天
Compress: true, // 是否压缩
})
log.Println("hello lumberjack")
}
✅ 特点:
import (
"go.uber.org/zap"
"gopkg.in/natefinch/lumberjack.v2"
)
func main() {
w := &lumberjack.Logger{
Filename: "logs/app.log",
MaxSize: 20,
MaxBackups: 5,
MaxAge: 30,
}
logger := zap.New(
zap.NewJSONEncoder(),
zap.AddStacktrace(zap.ErrorLevel),
zap.WriteTo(w),
)
logger.Info("hello zap")
}
import (
"github.com/sirupsen/logrus"
"gopkg.in/natefinch/lumberjack.v2"
)
func main() {
log := logrus.New()
log.SetOutput(&lumberjack.Logger{
Filename: "logs/app.log",
})
log.Info("hello logrus")
}
不修改 Go 代码
/var/log/myapp/*.log {
daily
rotate 7
compress
missingok
notifempty
copytruncate
}
⚠️ 缺点:
copytruncate 可能导致少量日志丢失除非你是为了学习,否则不建议,因为:
| 场景 | 推荐方案 |
|---|---|
| Go 服务 | ✅ lumberjack |
| 使用 zap / logrus | ✅ lumberjack |
| Docker / K8s | ✅ 输出到 stdout + 宿主机日志 |
| 传统 Linux 服务 | logrotate |
✅ 只用一个日志文件句柄
✅ 按大小切割,而不是时间
✅ 不要自己 rename 日志文件
✅ 容器里优先打到 stdout
如果你愿意,我可以:
你现在是哪种使用场景?