logrotate 配完日志却不轮转多半是少了 create 或权限不对

举报
phantomxjc 发表于 2026/11/04 08:35:33 2026/11/04
【摘要】 有台服务器跑了大半年没出问题,某天突然磁盘告警。上去一看,一个应用的日志文件 app.log 已经滚到了 30 多 G。我明明在 /etc/logrotate.d/ 下给它配了轮转规则,怎么就没生效?手动跑了一遍才发现问题不在"有没有配置",而在配置里少了关键几行,加上文件属主不对,导致轮转"看起来做了,实际啥也没发生"。 问题现象 为应用配了 logrotate 规则,预期是每天轮转、保留若干份

有台服务器跑了大半年没出问题,某天突然磁盘告警。上去一看,一个应用的日志文件 app.log 已经滚到了 30 多 G。我明明在 /etc/logrotate.d/ 下给它配了轮转规则,怎么就没生效?手动跑了一遍才发现问题不在"有没有配置",而在配置里少了关键几行,加上文件属主不对,导致轮转"看起来做了,实际啥也没发生"。

问题现象

为应用配了 logrotate 规则,预期是每天轮转、保留若干份、压缩旧日志。但现实中日志文件只增不减,磁盘被慢慢吃满。查 /var/lib/logrotate/status 发现该日志的轮转记录要么很旧、要么根本没有;手动 logrotate -d 调试时,要么提示"log does not need rotating",要么提示轮转了但文件大小纹丝不动。最诡异的是:日志明明被移走了(或改名了),应用却还在往一个"已不属于它"的路径写,磁盘占用一点没降。

排查过程

先看我的配置:

/var/log/myapp/*.log {
    daily
    rotate 7
    compress
    missingok
    notifempty
}

手动调试:

logrotate -d /etc/logrotate.d/myapp

输出里反复出现 considering log /var/log/myapp/app.log 然后 log does not need rotating。原因有二:一是我没加 size/minsize 触发条件,默认按 daily 周期走,但 logrotate 通常由 cron 每天调一次,若当天已经跑过、且没到下一个周期,就不会再转;更关键的是,这个应用不像 nginx 那样会重新打开日志文件——logrotate 把 app.log 改名成 app.log.1 后,应用的文件描述符还指向老 inode,继续往那个已被移走名字的文件里写,新生成的 app.log 反而是空的,磁盘占用自然不降。

再看权限:应用以普通用户 appuser 运行,但 logrotate 默认以 root 执行,配置里没有 su 指令,目录下也没有可写的归属,导致 create 出来的新文件属主是 root,应用写不进去,于是它死守着旧 fd。两个坑叠在一起,轮转等于白做。

根因

logrotate 默认行为是"把旧文件改名、然后靠应用重新打开来生成新文件"。如果应用不支持信号重载、不会重新打开日志(很多自研程序都这样),就必须用 copytruncate 或显式 create + 重新加载。而 create 缺省时,新文件属主/权限可能跟应用期望的不一致,应用无法写入,只能一直抱着旧 fd。另外,缺少 size/minsize 等触发条件,或者 cron 没按时调用 logrotate,也会让轮转不按预期发生。这不是 logrotate 坏了,而是配置没贴合应用的日志打开方式。

解决办法

  • 不能重载日志的程序,用 copytruncate:它先复制一份再截断原文件,不依赖应用重新打开,最省心。注意复制与截断之间有一瞬间可能丢几行日志,一般可接受。
  • 能重载的,配 create + postrotate:create 0644 appuser appuser 指定新文件属主,postrotate 里发信号或 reload 让应用重开日志(如 nginx 的 kill -USR1)。
  • 加触发条件:size 100M 或 minsize 100M,让日志到一定大小就转,不单靠天级别。
  • 权限对齐:若应用非 root,配置里加 su appuser appuser,避免 logrotate 以 root 建的文件应用写不了。
  • 调试先行:永远先 logrotate -d <配置> 看它会做什么,再去掉 -d 正式执行;定期检查 /var/lib/logrotate/status 确认真的转了。

小结

logrotate 不轮转,十有八九是"应用不会重开日志却没配 copytruncate/create"或"权限没对齐"。记住:先看应用是否支持信号重载,不支持就 copytruncate;新文件属主要跟运行用户一致;改完用 -d 调试、看 status 验证。把这几条补齐,日志轮转基本不会再掉链子。

【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0)

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。