logrus + lumberjack 是 go 日志轮转主流方案,因 logrus 缺乏轮转能力而 lumberjack 提供轻量、内建的按大小/时间切割、备份保留与压缩功能,且不依赖外部工具;需注意 writer 初始化时机、复用、目录预创建及关闭 flush,避免日志丢失。

GoLand 里配日志分级,本质是配代码逻辑,不是 IDE 设置
GoLand 本身不提供日志级别开关或轮转配置界面——它只是编辑器。所谓“配置”,全靠你在代码里选库、写判断、传参数。IDE 最多帮你高亮 logrus.Debug() 或提示 zap.NewAtomicLevel() 用法,但不会替你决定哪条日志该输出。
常见错误现象:在 GoLand 的 Run Configuration 里加了 LOG_LEVEL=debug 环境变量,但日志还是没 Debug 行——因为代码里没读这个变量,也没调 logrus.SetLevel()。
- 开发阶段快速启用分级:用
logrus,go get github.com/sirupsen/logrus后直接logrus.SetLevel(logrus.DebugLevel) - 生产环境需运行时切换:必须绑定
os.Getenv("LOG_LEVEL")+logrus.ParseLevel()+logrus.SetLevel()三步 - 别在
init()里硬编码logrus.SetLevel(logrus.InfoLevel),否则环境变量失效 - GoLand 的 Terminal 或 Run Config 中设置的环境变量,只影响启动进程,不影响后续热重载(如 air/restart)
logrus 分级 + lumberjack 轮转,两步封装就跑通
标准库 log 不支持分级,也不感知文件生命周期;logrus 填补分级,lumberjack 填补轮转——两者组合是 GoLand 项目里最省心的落地方式。
常见错误现象:用 os.OpenFile() 创建 *os.File 后直接塞给 logrus.SetOutput(),结果日志文件越来越大不切分——因为 lumberjack.Logger 是 io.WriteCloser,而裸 *os.File 不是。
GoLand 2026.1.1 是 2026.1 发布后的首个维护修正版本,适合已经开始体验 2026.1 新功能并希望同步补丁的开发者。它更适合用于入门项目、现有项目迁移测试和 IDE 行为验证。
- 安装依赖:
go get github.com/sirupsen/logrus和go get gopkg.in/natefinch/lumberjack.v2 -
lumberjack.Logger的Filename必须是绝对路径(如/var/log/myapp/app.log),相对路径在 daemon 场景下会写到 GoLand 工作目录,非预期位置 - 关键字段要显式设:
MaxSize: 100(单位 MB)、MaxBackups: 7、LocalTime: true(否则时间戳是 UTC)、Compress: true(Docker 镜像需预装 gzip) - 把
lumberjack.Logger实例传给logrus.SetOutput(),不是传*os.File
zap 性能高但热更新容易漏掉 AtomicLevel
用 zap 不是为了“更酷”,而是真有高吞吐场景(比如每秒万级日志)。但它比 logrus 多一个隐性门槛:级别控制不在 *zap.Logger 上,而在底层 zap.AtomicLevel。
常见错误现象:logger.WithOptions(zap.IncreaseLevel()) 调了没用;或者改了 atomicLevel.SetLevel() 但日志还是旧级别——因为构造 logger 时 core 没绑定这个 atomicLevel。
- 必须定义全局变量:
var atomicLevel = zap.NewAtomicLevel() - 构造
core时显式传入:core := zapcore.NewCore(enc, sink, atomicLevel) - 再用
zap.New(core)创建 logger,不能跳过 core 直接zap.NewDevelopment() - 轮转仍需
lumberjack或自定义WriteSyncer,zap自身不带轮转能力
轮转后日志“消失”?大概率是没关旧文件或并发冲突
日志轮转不是 rename 文件名,而是原子化地关闭旧文件句柄、打开新文件句柄、并更新写入目标。任何一步出错,都会导致日志写进已删除文件、或 panic 报 write: bad file descriptor。
常见错误现象:服务跑一两天后某次轮转失败,之后所有日志都不见了;或者 Docker 容器重启后日志又开始往旧文件写(因 lumberjack 未读取最新文件状态)。
- 用
lumberjack就别自己实现轮转——它内部已用sync.Mutex保证并发安全 - 手动实现轮转时,
Close()和OpenFile()必须在同一个锁区内完成,且log.SetOutput()要紧随其后 - 检查磁盘权限:
lumberjack创建日志目录时不会自动mkdir -p,父目录不存在会静默失败 - Docker 场景下,挂载的日志目录需提前
chown到容器内 UID,否则lumberjack写入失败无提示
app.log 是否变大、app.log.1 是否生成、以及 ls -la /var/log/myapp/ 输出的时间戳是否对齐——这些才是真实信号。










