lumberjack 可开箱即用实现日志切割,需正确导入 gopkg.in/natefinch/lumberjack.v2、设绝对路径 filename、maxsize 单位为 mb;centos 下注意 selinux 权限;logrotate 需配合 sighup 重载;compress 和轮转参数需权衡性能与磁盘风险。

用 lumberjack 实现开箱即用的日志切割
绝大多数 Golang 项目直接用 lumberjack 就够了,它稳定、轻量、无依赖,且与标准库 log 完全兼容。你不需要重写日志逻辑,只要替换 log.SetOutput() 的目标即可。
常见错误现象:用错 import 路径导致编译失败(比如用了 github.com/natefinch/lumberjack 但实际应为 gopkg.in/natefinch/lumberjack.v2),或忘记设置 Filename 导致日志写入空设备。
- 安装命令必须是:
go get gopkg.in/natefinch/lumberjack.v2 -
Filename必须是绝对路径(尤其在 CentOS 上),例如/var/log/myapp/app.log;相对路径容易因工作目录变化而写入失败 -
MaxSize单位是 MB(不是字节),设为10表示 10MB,不是 10 * 1024 * 1024 - 如果应用以 systemd 服务运行,确保
logrotate和lumberjack不冲突——二者别同时对同一个文件做轮转,否则可能丢失日志或报text file busy
示例片段:
log.SetOutput(&lumberjack.Logger{
Filename: "/var/log/myapp/app.log",
MaxSize: 10,
MaxBackups: 7,
MaxAge: 30,
Compress: true,
})
CentOS 下权限和路径的硬性约束
在 CentOS 上跑 Golang 日志切割,80% 的“切不动”问题其实跟代码无关,而是 SELinux、umask 或用户权限卡住的。日志路径不在 /var/log/ 下?那大概率会因 SELinux 策略被拦截。
典型错误信息:open /var/log/myapp/app.log: permission denied 或 operation not permitted(即使加了 sudo)。
- 先确认运行程序的用户对目标目录有写权限:
ls -ld /var/log/myapp,推荐属主设为运行用户,而非root - 创建目录后务必执行:
sudo setsebool -P httpd_can_network_connect 1(若用非标准端口或网络日志);更稳妥的是临时禁用 SELinux 测试:sudo setenforce 0 -
create权限(如0640)由lumberjack自动应用,但它只在首次创建文件时生效;已有文件的权限不会被修改,得手动chmod - 不要把日志写到
/tmp或用户家目录下用于生产——这些路径可能被系统清理策略误删
logrotate 配合 Golang 的边界场景
当你的 Golang 进程长期不重启(比如 daemon 或 systemd service),又想用系统级工具统一管理所有服务日志时,logrotate 是更可靠的选择。但它要求 Golang 进程能响应 SIGHUP 重新打开日志文件,否则会继续往已被 rename 的旧文件句柄写日志。
常见错误现象:logrotate 执行完后,新日志仍写进 app.log.2026-03-25,而 app.log 始终为空。
- 必须在 Golang 中监听
SIGHUP并重置log.SetOutput(),不能只靠logrotate的copytruncate(它会截断原文件,但 Go 的文件句柄仍指向旧偏移) - 配置里别漏掉
sharedscripts和postrotate段,用来通知你的进程 reload,例如:kill -SIGHUP $(cat /var/run/myapp.pid) -
create 0640 myuser mygroup中的用户组必须和 Golang 进程实际运行身份一致,id -gn可确认 - 测试命令:
sudo logrotate -f /etc/logrotate.d/myapp,再立刻检查ls -lt /var/log/myapp/
压缩、保留策略与磁盘失控风险
Compress: true 看似省空间,但在高 IO 场景下可能拖慢写入;MaxAge 和 MaxBackups 同时设置时,lumberjack 优先按数量清理,天数只是兜底——这点文档没明说,但实测如此。
容易被忽略的点:当日志写入速度极快(比如每秒千行),MaxSize 设太小会导致频繁 rename + open,引发大量短生命周期文件句柄,触发 too many open files 错误。
- 生产环境建议
MaxSize≥ 5MB,MaxBackups≤ 10,避免高频轮转 -
Compress: true会额外占用 CPU,若日志本身已用 gzip 传输或落盘到 NAS,可关掉 - 没有
lumberjack.Close()调用?那进程退出时文件句柄不会释放,MaxAge清理逻辑也不会触发——记得在main结束前调用 - 定期用
find /var/log/myapp -name "*.log.*" -mtime +30 -delete做双重保险,防止lumberjack清理失效
最麻烦的其实是混合使用:一边用 lumberjack 切割,一边又配了 logrotate。这时候哪个在管文件生命周期?没人说得清,出问题只能看 inode 变化。
golang免费学习笔记(深入):立即使用
在学习笔记中,你将探索golang的核心概念和高级技巧!











