iris 原生不支持日志切割,因其 logger 基于 io.writer 仅负责写入、不管理文件生命周期,也未集成 rollingfileappender 类机制;需借助 lumberjack.v2 或自定义 dailywriter 实现按天轮转,并注意清理旧日志与权限配置。

Iris 默认不带日志切割能力,Logger 输出到 os.Stdout 或文件后,就完全交由外部管理——想按天备份,必须自己接第三方 handler 或封装逻辑。
为什么 Iris 原生不支持切割
Iris 的 Logger 是基于 io.Writer 构建的,只负责写入,不感知文件生命周期。它没有内置 RollingFileAppender 类机制,也不绑定任何日志框架(如 Zap、Zerolog),所以无法像 Logback 那样声明式配置 TimeBasedRollingPolicy。
常见误操作是直接把 os.OpenFile 返回的 *os.File 传给 app.Logger().SetOutput(),结果日志一直追加到单个文件,磁盘迟早被撑爆。
用 TimedRotatingFileHandler(Python 风格)在 Go 里模拟
Go 生态没有官方 TimedRotatingFileHandler,但可用 gopkg.in/natefinch/lumberjack.v2 替代——它虽主打“按大小轮转”,但配合定时器 + 文件名模板,能稳定实现“按天归档”效果:
- 设置
lumberjack.Logger.MaxAge = 1(单位:天),并启用LocalTime: true,它会在每天零点自动关闭旧文件、新建带日期后缀的文件(如iris-access-2026-09-11.log) - 务必关闭
lumberjack.Logger.Compress = false,否则压缩会干扰日志实时读取(比如tail -f失效) - 文件名不能硬编码,需用
time.Now().Format("2006-01-02")动态拼接前缀,再交给lumberjack管理,否则多进程下可能冲突 - 若用
iris.Logger().SetOutput()接入,要确保该io.Writer实现了Write([]byte) (int, error)和Close() error(lumberjack.Logger满足)
整合 zerolog + 自定义 Writer 实现精确控制
更可控的方式是绕过 Iris 默认 logger,用 zerolog 构建结构化日志流,再注入自定义 writer:
- 定义一个
dailyWriter类型,内嵌*os.File,并在Write()中检查当前日期是否变更;变更则先Close()旧文件,再os.OpenFile(..., os.O_CREATE|os.O_APPEND|os.O_WRONLY)新建 - 用
time.Ticker每分钟触发一次checkRotate(),避免依赖写入时机——防止低流量服务某天没日志导致不切割 - 文件路径建议用绝对路径,例如
/var/log/myapp/iris-access-+time.Now().Format("2006-01-02")+.log,避免工作目录切换导致写入失败 - 注意并发:多个 goroutine 写日志时,
Write()方法内部需加sync.Mutex,否则os.File.Write可能因竞态丢数据
容易被忽略的清理与权限问题
按天切割只是第一步,没人清理旧文件,磁盘一样会满。别指望 lumberjack 自动删历史——它的 MaxBackups 只管“滚动编号”,不管“日期归档”。真正要保留最近 30 天,得额外加 cron 或 os.RemoveAll() 扫描删除:
- 写个简单清理函数,在应用启动时或每小时执行:
filepath.Glob("/var/log/myapp/iris-access-*.log"),过滤出time.Since(parsedDate) > 30*24*time.Hour的文件,os.Remove() - 确保运行 Iris 的用户对日志目录有
rwx权限,否则mkdir -p /var/log/myapp后仍可能报permission denied - 如果用 systemd 管理 Iris 进程,记得在 service 文件里加
ReadWritePaths=/var/log/myapp,否则 SELinux 或 systemd 特权模式会拦截写入











