logrotate 默认不支持 hourly,因 CentOS 7 版本(如 3.8.x)不识别该关键字,强行使用会报错或失效;必须通过 cron 每小时调用 logrotate -f 强制触发,并配合 dateext、dateformat -%Y%m%d%H、独立状态文件及 missingok/notifyempty 等配置模拟每小时轮转。

logrotate 默认不支持按小时轮转,它原生只支持 daily、weekly、monthly 和基于大小的 size 触发。想实现“按小时轮转”,必须绕过默认周期逻辑,用 cron 配合 logrotate -f 手动触发,并在配置中禁用时间判断、启用 dateext + hourly 语义模拟。
为什么不能直接写 hourly?
CentOS 7 的 logrotate(版本通常为 3.8.x)根本不识别 hourly 这个关键字 —— 写了会报错:error: bad rotation count 或直接忽略该行。官方文档和源码中均无 hourly 实现。强行加只会让配置失效,日志不轮转。
用 dateext + cron 模拟 hourly 轮转
核心思路:放弃 daily 等内置周期,靠 cron 每小时跑一次强制轮转,再用 dateext 和 dateformat 控制文件名带小时戳,避免覆盖。
-
dateext启用后,轮转文件后缀默认是-YYYYMMDD;加上dateformat -%Y%m%d%H就能变成-2026070820(当前小时) - 必须配
missingok和notifempty,否则 cron 每次都因“无变化”或“空文件”报错退出 -
rotate值要设大些(比如rotate 24),因为每小时一个文件,24 小时才删最老的 - 不要用
compress配合 hourly —— 每小时 gzip 一次 I/O 压力大,且小文件压缩率低;改用nocompress或后期用 logrotate 外部脚本批量压缩
示例配置(以 /var/log/messages 为例):
/var/log/messages {
nocompress
dateext
dateformat -%Y%m%d%H
rotate 24
missingok
notifempty
create 0640 root root
sharedscripts
postrotate
# 可选:通知 rsyslog 重新打开文件(若用 systemd-journald 则无需)
systemctl kill --signal=SIGUSR1 rsyslog.service >/dev/null 2>&1 || true
endscript
}配置 cron 每小时执行一次
logrotate 不会自己每小时跑,必须手动加定时任务:
- 编辑
/etc/cron.hourly/logrotate-hourly(注意权限:需chmod +x) - 内容写:
#!/bin/bash\n/usr/sbin/logrotate -s /var/lib/logrotate/logrotate.status.hourly /etc/logrotate.d/messages-hourly - 把上面的配置存为
/etc/logrotate.d/messages-hourly,而非复用主配置(避免和 daily 冲突) -
-s指定独立的状态文件路径,防止和 daily 任务共用/var/lib/logrotate/status导致时间戳混乱
验证 cron 是否生效:ls -l /etc/cron.hourly/ 看文件是否存在且可执行;grep CRON /var/log/cron 查看最近一小时是否有执行记录。
容易踩的坑
实际部署时最常出问题的几个点:
- 忘了
sharedscripts却在postrotate里调服务重启 —— 导致每匹配一个日志文件就执行一次命令(比如/var/log/messages和/var/log/secure都匹配时,rsyslog被杀两次) -
dateformat必须紧接在dateext下一行,且格式字符串必须用%开头(如-%Y%m%d%H),写成%Y-%m-%d %H会失败 - 没单独指定
-s状态文件,导致 hourly 和 daily 任务互相干扰,出现“已轮转过”跳过或重复轮转 - 用
copytruncate替代create—— 对rsyslog这类持续写入的服务,copytruncate有极小概率丢日志(拷贝和清空之间存在窗口),create+postrotate发信号更可靠
真正需要 hourly 轮转的场景(比如高频审计日志、调试期 trace 日志),务必确认磁盘 I/O 和 inode 数量能扛住每小时新建文件;长期运行前,先用 logrotate -f -v 手动试跑几次,检查生成文件名、权限、是否真调用了 postrotate。


















