logrotate每小时切割需同时配置hourly参数和系统级cron hourly调度,仅改daily为hourly无效;必须存在/etc/cron.hourly/目录及对应crontab条目,或手动添加/etc/cron.d/logrotate-hourly定时任务。

logrotate 配置每小时切割的关键参数
默认 logrotate 按天执行,要改成每小时,不能只改 daily 为 hourly 就完事——系统级 cron 本身不默认启用 hourly 任务。必须确认底层调度存在,再配 logrotate 规则。
先检查 cron 是否运行 hourly 任务:/etc/cron.hourly/ 目录是否存在且有可执行脚本;再确认 /etc/crontab 或 /etc/anacrontab 中是否包含类似 01 * * * * root run-parts /etc/cron.hourly 的行。缺一不可。
-
hourly在 logrotate 配置中仅表示“期望每小时轮转”,实际触发依赖外部 cron 调用logrotate命令 - 推荐显式在
/etc/cron.d/logrotate-hourly中添加:0 * * * * root /usr/sbin/logrotate /etc/logrotate.hourly.conf - 对应配置文件建议单独建为
/etc/logrotate.hourly.conf,避免和 daily 配置冲突
logrotate.hourly.conf 示例与易错点
以下是最简可用配置,重点在 dateformat 和 rotate 控制:
"/var/log/myapp.log" {
hourly
missingok
notifempty
compress
delaycompress
dateformat -%Y%m%d-%H
rotate 24
sharedscripts
postrotate
systemctl kill -s USR1 myapp.service > /dev/null 2>&1 || true
endscript
}
常见错误:
-
dateformat必须以-开头,否则生成的归档名不含分隔符,logrotate后续无法识别旧日志(如myapp.log-2024101514vsmyapp.log-20241015-14) - 不要用
create,除非应用本身不自动重建日志文件;否则每小时重建可能引发权限或打开文件句柄问题 -
sharedscripts+postrotate是安全发信号的前提;若漏掉sharedscripts,postrotate可能在每个匹配文件上重复执行
应用不支持 USR1 信号时的替代方案
很多程序(比如 Python 的 logging.FileHandler 默认行为、某些 Java 应用)不监听 USR1,此时靠信号 reopen 日志会失败,导致新日志继续写入旧文件,切割形同虚设。
可行解法只有两个:
- 改应用:用支持
watched或timed轮转的 logger(如 Python 的RotatingFileHandler配maxBytes+backupCount,但注意它不按小时对齐) - 不动应用:用
copytruncate—— logrotate 先复制当前文件,再清空原文件。缺点是可能丢失正在写入的最后几行(取决于应用 flush 频率),但胜在通用
加 copytruncate 后,postrotate 可删掉,因为不再需要通知应用重开文件。
验证与调试技巧
别等一小时看结果。用 logrotate 手动测试:
- 加
-d看干跑输出:logrotate -d /etc/logrotate.hourly.conf,确认匹配到文件、时间戳格式、归档路径都正确 - 加
-f强制执行:logrotate -f /etc/logrotate.hourly.conf,立刻生成带-YYYYMMDD-HH后缀的压缩包 - 检查
ls -lt /var/log/myapp.log*,确认旧文件被重命名、新文件权限和所有者没变、压缩包存在且非空
最常被忽略的是:logrotate 不校验目标目录是否可写、磁盘是否有空间、gzip 是否在 PATH 里——这些错误不会直接报出,只会静默失败,得靠 -d 输出里的 warning 行定位。











