讲解 logrotate 按时间容量轮转、压缩保留、postrotate、copytruncate、调试和已删除文件占用。
应用日志如果只追加不轮转,最终可能占满云服务器磁盘。logrotate 可以按时间或容量切割、压缩并删除历史日志,但配置是否安全取决于应用能否在轮转后重新打开日志。
安全入口:应用日志规则通常放在 /etc/logrotate.d/。先用 logrotate --debug 只读解析,再决定轮转方式:应用支持重新打开日志时优先重命名后发送 HUP;无法重开时才考虑 copytruncate。错误保留策略会删历史日志,误配还会让应用继续写已删除文件。

先确认谁在管理日志
systemd 服务可能写入 journald;Docker 有自己的日志驱动;Nginx 和应用也可能写普通文件。不要让多个工具轮转同一个文件。
基础配置
/var/log/example-api/*.log {
daily
rotate 14
size 100M
compress
delaycompress
missingok
notifempty
create 0640 app app
sharedscripts
postrotate
/bin/systemctl kill -s HUP example-api.service 2>/dev/null || true
endscript
}保存到 /etc/logrotate.d/example-api。用户、服务名、信号和路径必须匹配实际应用,只有应用支持 HUP 时才发送该信号。
rename/create 与 copytruncate
标准方式是重命名旧文件、创建新文件,再通知应用重新打开;边界清晰,通常更可靠。copytruncate 适合无法重新打开日志的旧程序,但复制和截断之间可能丢少量日志,大文件也会增加 I/O。
测试配置
sudo logrotate --debug /etc/logrotate.d/example-api
sudo logrotate --verbose --force /etc/logrotate.d/example-api
ls -lh /var/log/example-api/
sudo lsof +L1--debug 不修改文件。强制轮转会真实操作,应先在测试环境或维护窗口执行,并确认应用继续写入新文件。
确定保留策略
| 维度 | 需要确认 |
|---|---|
| 排障周期 | 通常回看多长时间 |
| 磁盘预算 | 峰值日志量乘以保留期 |
| 合规要求 | 是否需要长期归档 |
| 集中日志 | 本地保留多少缓冲 |
常见故障
- 轮转后仍写旧文件:应用没有重新打开句柄。
- 配置不执行:尚未达到时间或容量条件。
- 磁盘未释放:进程仍打开已删除文件。
- 轮转后报错:信号或文件权限不匹配。
边界条件
logrotate 不是集中日志和备份系统。重要审计日志应传输到独立存储并设置访问和防篡改策略。
先看谁在写
sudo lsof /var/log/YOUR_APP.log ; sudo logrotate --debug /etc/logrotate.conf替换路径。第一项确认进程和句柄,第二项只解析规则。系统可能由 systemd timer 或 cron 调用,不要重复创建计划。
两种方式
标准方式重命名当前日志,再在 postrotate 通知服务重开,切换更清晰。copytruncate 先复制再截断,适合无法重开的老程序,但窗口内可能丢写入,大日志还增加 IO。能正确重开时不要默认 copytruncate。
规则检查
- 按天/容量触发、保留数量和压缩是否符合审计。
create的属主、组和权限是否允许继续写。postrotate服务名与信号是否正确。- 通配符是否误含压缩文件或无关日志。
空间与回退
df 很满而 du 对不上时,用 lsof +L1 查已删除仍占用文件;让服务重开或维护重启,不结束未知进程。强制测试后检查新日志增长、旧日志压缩、权限和空间。修改前保存旧规则;应用停止写入时恢复旧规则并发送官方支持的信号。没有备份或保留确认时不能删唯一日志。
不同日志要分开保留
访问日志、错误日志、审计日志和应用调试日志的价值、增长速度与合规要求不同,不应共享一个保留数字。先估算每日增长和可用空间,给审计类日志配置更严格的转存与权限。压缩能节省空间,但首次压缩可能增加 CPU 和 IO,应避开业务高峰并观察运行时间。

