go-logging 本身不支持日志滚动,需配合 lumberjack 等外部组件实现按大小或时间轮转,其 backend 仅负责分级过滤与格式化输出,不处理文件切分、归档或清理。

直接用 go-logging 无法实现日志滚动——它不处理文件切分、归档或清理,只管分级和输出。滚动必须靠外部组件(如 lumberjack)或系统工具(如 logrotate)补足。
go-logging 本身不支持滚动,别指望 SetOutput 能自动切文件
go-logging 的 Backend 只负责接收日志、按模块/级别过滤、格式化后写入 io.Writer。它完全不管这个 Writer 是不是文件、文件会不会满、旧日志要不要删。你传一个普通 *os.File 给它,日志就一直追加写,直到磁盘爆掉。
- 常见错误现象:日志目录里只有一个
app.log不断膨胀,MaxSize或daily配置根本没反应 - 原因:这些参数不是
go-logging的配置项,它压根不认识 - 正确做法:把
go-logging的输出目标设为一个「自带滚动能力」的io.WriteCloser,比如lumberjack.Logger
用 lumberjack 接 go-logging 实现按大小滚动
这是最稳妥的组合:用 go-logging 做分级控制,用 lumberjack 做文件滚动,两者职责分明,互不干扰。
-
Filename必须是绝对路径,或确保进程有权限写入的相对路径;目录不存在时lumberjack不会创建,静默失败 → 日志全丢 -
MaxSize单位是 MB,检查的是「写入前」文件大小,不是实时统计 → 实际单文件可能略超设定值 -
MaxBackups和MaxAge是「或」关系:任一条件满足即清理,不是两个都满足才删 -
Compress: true会阻塞写入,高并发场景慎用;若只需保留最近 N 天,建议关压缩、开MaxAge
示例:
使用 uber-go/dig 在 Golang 中实现依赖注入——基于反射容器,提供 Provide/Invoke、dig.In/dig.Out 参数与结果对象,支持命名依赖等
import (
"github.com/op/go-logging"
"gopkg.in/natefinch/lumberjack.v2"
)
backend := logging.NewLogBackend(&lumberjack.Logger{
Filename: "logs/app.log",
MaxSize: 10,
MaxBackups: 5,
MaxAge: 28,
Compress: false,
}, "", 0)
leveled := logging.AddModuleLevel(backend)
leveled.SetLevel(logging.INFO, "") // 全局默认
leveled.SetLevel(logging.DEBUG, "database") // database 模块开 debug
leveled.SetLevel(logging.WARNING, "auth") // auth 模块只打 warning 及以上
logging.SetBackend(leveled)
按时间滚动(每日一文件)需手动切换 Writer
lumberjack 不支持「每天新建带日期后缀的文件」,它只做大小滚动。要实现 app-2026-07-01.log 这种命名,得自己封装逻辑,并确保线程安全。
- 每次写日志前检查当前日期是否变化,不一致则关闭旧文件、打开新文件
- 必须用
os.O_CREATE | os.O_APPEND | os.O_WRONLY打开,否则会清空已有内容 - 切换动作必须加
sync.Mutex,否则多 goroutine 并发触发会导致use of closed network connectionpanic - 不要在
Write方法里做filepath.Glob或os.Remove等耗时操作,会拖慢所有日志调用
go-logging + lumberjack 的权限与部署坑
在 CentOS 或其他 Linux 生产环境部署时,权限问题比本地开发更易暴露。
-
lumberjack写文件时用的是进程运行用户(如www-data),不是 root;确保该用户对logs/目录有rwx权限 - 如果程序用 systemd 启动,
WorkingDirectory和UMask会影响日志路径解析和文件权限,建议显式设UMask=0002 - 符号链接会被
lumberjack当作普通文件处理,不跟踪目标变更;避免把logs/app.log设为软链到/var/log/myapp/current - 容器环境里,挂载卷的属主可能和进程用户不匹配,启动前先
chown -R www-data:www-data /app/logs
滚动这件事,本质是「关旧、开新、删老」三步原子操作;go-logging 只管中间那条线上的事,前后两步得你亲手攥紧。
golang免费学习笔记(深入):立即使用
在学习笔记中,你将探索golang的核心概念和高级技巧!










