发布于2026-07-09 阅读(0)
扫一扫,手机访问
Go 标准库的 log 包确实方便,但如果你指望它自带日志轮转功能,那只能失望了——它只负责把日志写到文件里,文件无限增长怎么办?要么用第三方库,要么自己手写一套。直接用 log.SetOutput() 接一个文件句柄而不做任何轮转处理,结果就是单文件撑爆磁盘,排查问题都找不到入口。

社区里常见的轮转方案有几个:lvg/logrotator、lestrrat-go/file-rotatelogs 和 gopkg.in/natefinch/lumberjack.v2。其中 lvg/logrotator 是真正的“轻量级选手”——整个库就一个文件,零外部依赖,行为透明到可以一眼看懂轮转逻辑。如果你的项目已经有一套日志处理流程,只是想塞一个简单的轮转器进去,它非常合适。反观 lumberjack,虽然稳定但默认开启压缩和归档,逻辑稍重,低配环境下频繁 I/O 操作可能引起阻塞。
logrotator.New 返回的是 io.WriteCloser,可以直接传给 log.SetOutput,接入极其简单。MaxSize(字节数)和 MaxBackups(保留的旧文件数)。os.MkdirAll,首次写日志就会直接 panic。os.Rename,不涉及文件拷贝,性能开销几乎可以忽略。很多新手栽在初始化失败或者忘记关闭轮转器上——程序退出时日志没刷盘,或者文件句柄泄漏,日志突然不写了。这种问题往往在半夜出故障时才暴露。
log.SetOutput 之前完成初始化,并且要检查返回的 error。示例:rotator, err := logrotator.New("app.log", logrotator.MaxSize(10*1024*1024), logrotator.MaxBackups(5))。os.MkdirAll(filepath.Dir("app.log"), 0755),否则你会看到 open app.log: no such file or directory 直接 panic。rotator.Close(),否则最后一批缓冲日志可能没来得及刷盘就丢失了。lumberjack 功能强,但配置项多,稍不留神就埋下隐患。最常见的误区和它们背后的原因如下:
LocalTime: true 这个参数必须设为 true。否则轮转后的文件名里时间戳是 UTC 的,和你系统日志里用本地时间对不上,排查问题时很混乱。MaxAge 和 MaxBackups 是“或”关系——任意一个条件满足就会触发轮转。但要注意:MaxAge=0 表示禁用时间轮转,只依赖文件大小;如果两个都设为 0,那日志就不会有任何轮转。0600,如果其他进程(比如日志采集 agent)需要读取,必须显式设置 Perm: 0644。sync.Mutex 保护写操作,高并发场景下比 logrotator 稍慢一点,不过大多数业务场景下可以忽略。轮转不是加个库就能高枕无忧——关键要看轮转时机是否和业务节奏匹配(比如大促期间调小 MaxSize),归档路径是否隔离(别和临时文件混在一起),以及退出时 Close 是否被 defer 正确包裹。任意一点遗漏,都可能让日志在某个凌晨突然消失,那时候再找原因就晚了。
售后无忧
立即购买>office旗舰店
售后无忧
立即购买>office旗舰店
售后无忧
立即购买>office旗舰店
售后无忧
立即购买>office旗舰店
正版软件
正版软件
正版软件
正版软件
正版软件
1
2
3
7
8