revel框架默认不支持日志轮转,需手动集成lumberjack等第三方handler或借助logrotate等外部工具,否则runtime/logs/app.log会无限增长;推荐使用lumberjack.v2配置maxsize、maxbackups和maxage实现按大小与时间双维度轮转,并注意区分应用日志与访问日志的归档策略。

Revel 框架默认不带日志轮转,必须手动集成第三方 handler 或改用外部工具(如 logrotate),否则 runtime/logs/app.log 会无限增长直到磁盘爆满。
Revel 默认日志输出路径和限制
Revel 启动后,日志默认写入 runtime/logs/app.log,使用的是 Go 标准库 log 包封装的简单文件写入器。它没有内置轮转能力,也不支持 maxBytes 或 when='D' 这类参数。
常见错误现象包括:
- 日志文件单日突破 2GB,
tail -f app.log卡死 - 运维巡检发现
/var/lib/revel/runtime/logs/占用 98% 磁盘,但无任何归档文件 - 重启 Revel 后日志从头覆盖,丢失关键故障现场
用 lumberjack 实现按大小轮转(推荐)
Go 生态最稳定、被 Revel 社区广泛采用的日志轮转方案是 gopkg.in/natefinch/lumberjack.v2。它轻量、无依赖、线程安全,适配 Revel 的 revel.AppLog 和 revel.TRACE。
实操步骤:
- 安装:运行
go get gopkg.in/natefinch/lumberjack.v2 - 在
app/init.go的init()函数里替换默认输出器:
import "gopkg.in/natefinch/lumberjack.v2"
func init() {
revel.InterceptMethod((*App).Begin, revel.BEFORE)
// 替换 AppLog 输出目标
revel.AppLog.SetOutput(&lumberjack.Logger{
Filename: revel.BasePath + "/runtime/logs/app.log",
MaxSize: 100, // MB
MaxBackups: 7,
MaxAge: 28, // 天
Compress: true,
})
}
注意点:
-
MaxSize单位是 MB(不是字节),设为100表示每个日志文件最多 100MB - 不要设
MaxAge: 0,否则旧备份永不删除;MaxBackups和MaxAge是“与”关系,任一条件超限即清理 - Revel 的
revel.WARN/revel.ERROR日志会正常进入轮转,但revel.TRACE(调试级)需额外确认是否启用,避免轮转压力过大
海量 Web 访问日志(access log)另起通道
Revel 的 AppLog 只管应用层日志(panic、DB 错误等),HTTP 访问日志(status code、path、latency)默认不记录。若要存海量访问日志,不能塞进 app.log,否则混合日志无法分析、轮转策略冲突。
正确做法是分离通道:
- 启用 Revel 内置 access log:在
conf/app.conf中设revel.access.log = true,它会输出到stdout(即容器日志或 systemd journal) - 若需落地为文件并轮转,**不要**用 Revel 自己写文件,而是交给宿主机 logrotate 或 Docker
max-file控制:
Docker 场景下,在 docker run 或 compose.yml 中加:
logging:
driver: "json-file"
options:
max-size: "100m"
max-file: "7"
Linux 宿主机场景下,新建 /etc/logrotate.d/revel-access:
/var/lib/docker/containers/*/*-json.log {
daily
rotate 7
compress
missingok
copytruncate
}
关键区别:
- 应用日志(
app.log)走lumberjack,强调结构化、可追溯、含堆栈 - 访问日志(
json.log)走系统级轮转,强调吞吐、低延迟、可对接 ELK - 两者绝对不可混用同一文件或同一 handler,否则
backupCount=7对访问日志毫无意义——它每秒几百行,7 个备份撑不过 2 小时
真正容易被忽略的是时间精度和时区。lumberjack 的 MaxAge 判断基于文件修改时间(mtime),而 Revel 启动后可能长时间不写日志,导致“空闲日志文件”迟迟不被清理;访问日志的 copytruncate 在高并发下有极小概率丢 1–2 行——这些细节线上跑一周才会暴露,别等磁盘告警才想起来查。











