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