logrotate配置文件须置于/etc/logrotate.conf或/etc/logrotate.d/目录下,权限644、无扩展名;生效需满足权限与命名规范,调试用logrotate -d,轮转触发需注意size与time指令逻辑。

logrotate 配置文件写在哪、怎么生效
logrotate 不会自动扫描任意位置的配置,必须放在它明确加载的路径里才管用。默认只读 /etc/logrotate.conf,而它通常会通过 include /etc/logrotate.d/ 加载目录下所有非隐藏、无扩展名的文件。
常见错误是把配置扔进 /etc/logrotate.d/myapp 后发现没触发——八成是文件权限不对(logrotate 要求配置文件不能被组或其他用户写,否则直接跳过),或者文件名带了 .conf 或 ~ 后缀(比如 myapp.conf 或 myapp.bak)。
- 确保配置文件权限为
644,属主 root - 文件名不要含点号或波浪线,例如用
/etc/logrotate.d/nginx,别用/etc/logrotate.d/nginx.conf - 改完后手动运行
logrotate -d /etc/logrotate.conf(-d 是 debug 模式)看是否识别到你的配置和日志路径
按大小轮转却一直不触发?检查 size 和 daily 的冲突
size 和 daily(或 weekly、monthly)可以共存,但行为容易误解:logrotate 默认只在「满足时间周期且日志达到 size」时才轮转,不是任一条件满足就转。也就是说,设了 daily + size 100M,哪怕日志当天涨到 200M,只要还没到第二天零点,就不会转。
想真正“涨满就转”,得去掉时间指令,只留 size,并加 copytruncate(防止服务因文件被 mv 而写失败):
var/log/app/*.log {
size 100M
copytruncate
rotate 7
compress
}
-
copytruncate安全但有极小概率丢最后一小段日志(写入和截断之间的时间窗) - 如果应用支持重打开日志(如 nginx 支持
kill -USR1),优先用create+ 信号通知,比copytruncate更可靠 -
size值不支持 KB 单位缩写,只能写100M或104857600,不能写100MB或100k
归档压缩后空间没释放?注意 compresscmd 和 delaycompress
logrotate 默认用 gzip 压缩,但如果你换了 compresscmd(比如改成 xz),必须同步配 compressext,否则旧压缩文件可能被误删或新文件扩展名错乱。更隐蔽的问题是 delaycompress:它会让压缩延迟一轮,即本次轮转不压,下次轮转时才压上一轮的文件。
这在磁盘紧张时很危险——你看到日志已轮转,但旧文件仍以明文存在,直到下一轮才压缩。典型表现是 ls -lh 看到 app.log.1 很大,但 app.log.2.gz 已存在。
- 确认是否真需要
delaycompress:只有当应用可能还在写.1文件(比如没及时 reload)时才用,多数现代服务不需要 - 换压缩工具时,务必配对设置:
compresscmd /usr/bin/xz+compressext .xz - 测试压缩效果:手动跑一次
logrotate -f /etc/logrotate.d/myapp,再立刻ls -lh看文件状态
备份到远程机器?别让 logrotate 直接 ssh
logrotate 本身不支持 rsync 或 scp,硬塞 postrotate 脚本调 rsync 很容易出问题:超时、连接中断、权限失败都会导致整个轮转流程卡住或静默失败。更糟的是,如果远程备份慢,logrotate 可能阻塞后续轮转,造成日志堆积。
稳妥做法是把归档和传输解耦:logrotate 只负责本地轮转和压缩,再用独立的定时任务(比如 crontab)定期拉取最新压缩包上传。
- 在 logrotate 配置里用
olddir /var/log/archived把旧日志集中挪到一个目录,方便 rsync 扫描 - 单独写个脚本,用
find /var/log/archived -name "*.gz" -mmin +60找一小时前生成的包,避免传一半的日志 - rsync 加
--remove-source-files,传完删本地,但前提是确认远程写入成功(加--dry-run先测)
真正难的不是传出去,而是传出去之后还能快速定位某天某服务哪一行日志——所以归档路径结构、文件命名规则、索引记录,这些往往比传输本身花的时间多得多。










