logrotate需显式配置应用日志并验证启用状态,否则磁盘易被撑满;须检查systemd timer或cron、测试配置、确认postrotate脚本正确性及句柄更新。

logrotate 不是“装了就能用”的工具,它默认只管系统日志(如 /var/log/syslog),你自己的应用日志(比如 /data/myapp/logs/app.log)必须显式配置,否则会一直疯长——这是绝大多数磁盘占满事故的根源。
怎么确认 logrotate 真正在跑
别信“预装就等于启用”。很多新装系统或容器环境压根没激活 daily cron 调度:
- 运行
sudo systemctl list-timers | grep logrotate,有输出才说明 systemd timer 已启用;若无,检查/etc/cron.daily/logrotate是否存在且可执行 - 手动触发一次模拟运行:
sudo logrotate -d /etc/logrotate.conf,看输出里有没有报错(比如权限拒绝、路径不存在) - 查状态文件:
cat /var/lib/logrotate/status,最后一行时间戳是否在最近24小时内?不是,说明 cron 没跑成
为自定义日志写独立配置文件
把规则塞进 /etc/logrotate.d/ 是最安全、最易维护的做法,全局配置 /etc/logrotate.conf 少动为妙:
- 新建文件:
sudo nano /etc/logrotate.d/myapp - 内容必须包含日志路径、大括号块、至少一个触发条件(
daily或size 100M)和rotate数值 - 关键参数要对齐实际需求:高写入服务(如 Nginx)建议加
copytruncate,避免依赖服务 reload;低频服务可用create 0644 myuser mygroup - 务必用绝对路径写
postrotate里的命令,例如/bin/kill -USR1 `cat /var/run/myapp.pid`,不能写kill
为什么 postrotate 经常失效
postrotate 不是“执行完就完事”,它失败时 logrotate 默认不报错,但旧日志句柄不会释放,导致新日志继续写进 .1 文件——这是日志“看似轮转了,实则还在涨”的元凶:
- 先验证命令能否手动执行成功:
sudo /bin/kill -USR1 `cat /var/run/myapp.pid 2>/dev/null` - 加
sharedscripts——否则每个匹配到的日志文件都会单独执行一遍postrotate,容易重复发信号 - 用
|| true收尾(如/bin/kill ... || true),防止某次 pid 文件暂缺导致整个轮转中断 - 不要依赖
systemctl reload:某些服务(如早期 rsyslog)reload 会丢日志,USR1信号才是标准做法
调试时最容易忽略的三件事
配置写完不测试 = 白写。真正上线前必须做这三步,缺一不可:
- 语法检查:
sudo logrotate -d /etc/logrotate.d/myapp,重点看 “error” 或 “warning” 行,尤其是 “file not found” 和 “permission denied” - 强制执行一次:
sudo logrotate -vf /etc/logrotate.d/myapp,-v显示动作,-f强制触发,立刻看到归档文件生成 - 验证句柄是否更新:用
lsof -p $(cat /var/run/myapp.pid) | grep log,确认进程打开的还是app.log,而不是app.log.1
logrotate 的复杂点不在语法,而在它和应用进程的协作时机——你写的每一条 postrotate 命令,都得经得起“进程正在疯狂写日志”这个最坏场景的考验。漏掉 sharedscripts 或写错信号类型,轮转就会静默失败,而磁盘空间不会等你发现。











