Revel 默认日志不支持按日期切分,需用 lumberjack 手动替换日志器或使用 logrotate 外部轮转;关键配置包括 LocalTime: true、绝对路径日志文件及权限检查。

Revel 默认不支持按日期切分日志文件
Revel 内置的 revel.INFO、revel.ERROR 等日志器直接写入 stdout 或指定文件(如 logs/app.log),但底层用的是 Go 标准库 log,**不带轮转(rotation)或按日期切分能力**。你看到的日志持续追加、文件越来越大,是预期行为,不是配置遗漏。
用 lumberjack 实现按天切分需手动替换日志输出器
Revel 允许通过 revel.InitLoggers() 替换默认日志器,主流做法是用 gopkg.in/natefinch/lumberjack.v2 —— 它支持按大小、按时间(含 LocalTime: true + MaxAge: 7)切分。关键点不是“加个配置”,而是重写日志初始化逻辑:
- 在
app/init.go的init()函数中,找到revel.InitLoggers()调用位置(通常在revel.Harness.Init()之前) - 创建
*lumberjack.Logger实例,设置Filename(如"logs/app.log")、MaxSize(单位 MB)、MaxAge(天数)、LocalTime: true(否则按 UTC 切分,可能错一天) - 调用
revel.SetLogger("INFO", log.New(...))和revel.SetLogger("ERROR", ...)分别替换两个日志器 - 注意:
lumberjack不处理日志格式,需用log.SetFlags()补齐时间戳、文件名等,否则切分后日志行缺少上下文
避免踩坑:时间字段、权限与测试路径
按日期切分最常出问题的不是代码,而是环境细节:
-
LocalTime: true必须显式设为true,否则MaxAge和文件名中的日期都按 UTC 计算,国内服务器会晚 8 小时归档 - 确保 Revel 进程对
logs/目录有写权限,且磁盘空间足够——lumberjack在切分失败时会静默降级为追加写,不易察觉 - 开发时用
revel run启动,日志路径基于revel.AppPath(即项目根目录),但生产用二进制部署时,AppPath可能失效;建议日志路径用绝对路径(如/var/log/myapp/app.log)或通过环境变量注入 - 测试切分逻辑时,不要等真实 24 小时:可临时把
MaxAge设为1,改系统时间跳过一天,或直接调用logger.Rotate()强制触发
替代方案:交给外部工具更轻量
如果你只想要按天切分,不依赖日志内容做分析,其实没必要侵入 Revel 初始化流程。Linux 下用 logrotate 是更稳妥的选择:
- 配置
/etc/logrotate.d/myapp,指定daily、rotate 30、compress - 关键要加
copytruncate:因为 Revel 进程持有日志文件句柄,logrotate重命名后需清空原文件,否则新日志仍写入旧 inode - 无需改任何 Go 代码,上线即生效,运维也熟悉这套机制
真正需要代码层切分的场景,通常是日志要上传到中心系统、或必须保证单个文件不超过某大小以适配采集 Agent —— 普通 Web 应用,logrotate 足够可靠,也更少出错。


















