logrotate配置不生效主因是定时任务未触发,需检查配置路径、include语句及cron或systemd定时器;按大小切割用size参数并配copytruncate;journald爆满应设systemmaxuse和maxretentionsec;应用直写日志须用轮转库或prerotate通知重开。

logrotate 配置不生效的常见原因
直接写好 /etc/logrotate.d/your-script 却发现日志从不切割?大概率是 logrotate 没跑,或没匹配到文件。logrotate 默认只在每天 /etc/cron.daily/logrotate 里触发一次,不会实时监听;且要求日志文件路径必须和配置中完全一致(包括软链接目标),权限需为 root 可读。
验证是否运行:手动执行 logrotate -d /etc/logrotate.conf(-d 是 debug 模式,不实际切割,只打印判断逻辑);检查输出里是否有 “rotating pattern” 和 “renaming” 相关行。若没有,说明配置未命中。
- 确保日志文件存在且非空,logrotate 默认跳过空文件
- 如果脚本用
sudo或非 root 用户写日志,logrotate 需有对应读取权限(建议日志属主设为root:adm,权限644) - 避免在配置里用通配符如
/var/log/myscript/*.log,除非你明确需要批量匹配;单文件更可靠,写死路径
Python 脚本内嵌滚动的实操选择
不想依赖系统级工具?logging.handlers.RotatingFileHandler 和 TimedRotatingFileHandler 是标准方案,但行为和运维预期常有偏差——比如按大小切割时,backupCount=5 表示最多保留 5 个归档,不是“保留最近 5 天”。
关键参数差异:
-
maxBytes:达到后立即切割,但不保证精确(比如写入 1KB 超限时,会先写完当前行再切,实际可能超几百字节) -
backupCount:旧日志被.1,.2… 命名,.1永远是最新归档,每次切都重命名,不是按时间戳 -
when='D'的TimedRotatingFileHandler在凌晨触发,但若进程未持续运行,就错过当天切割(适合常驻进程,不适合 cron 每小时跑一次的脚本)
简单示例(按大小滚动):
import logging
from logging.handlers import RotatingFileHandler
<p>handler = RotatingFileHandler(
'/var/log/myscript.log',
maxBytes=10_000_000, # 10MB
backupCount=7,
encoding='utf-8'
)
logger = logging.getLogger('myscript')
logger.addHandler(handler)
logger.setLevel(logging.INFO)</p>
Shell 脚本里用 logrotate 手动触发切割
某些场景下,脚本需要在退出前强制切一次(比如调试时频繁启停),不能等 cron。这时可临时调用 logrotate 并指定配置片段。
做法:把切割规则写成独立配置文件(如 /tmp/myscript-logrotate.conf),然后运行 logrotate -f /tmp/myscript-logrotate.conf(-f 强制执行)。
- 配置里必须写绝对路径,且
create指令要带权限和用户,例如:create 644 www-data adm - 注意
postrotate脚本里不能用$1(logrotate 不传参),要用ls -t /var/log/myscript*.log.* | head -n1这类方式找最新归档 - 如果脚本本身以非 root 运行,
logrotate -f必须用 sudo,且 sudoers 需免密配置(如myuser ALL=(root) NOPASSWD: /usr/bin/logrotate)
切割后日志时间戳混乱怎么办
用 RotatingFileHandler 按时间切,发现归档文件名是 app.log.2024-05-20,但内容里第一条日志却是 2024-05-21 00:02?这是因为 handler 在 00:00 检查时间,但真正写入首条日志在几分钟后——归档名按检查时刻定,内容按写入时刻记。
更稳的做法是放弃自动时间戳命名,改用固定后缀 + 外部压缩:
- 用
RotatingFileHandler切出app.log.1~app.log.7 - 在
postrotate里用date -r app.log.1 +%Y-%m-%d提取文件修改时间,重命名为app.log.2024-05-20.gz - 或直接用
find /var/log -name 'app.log.*' -mtime +30 -delete替代backupCount,逻辑更透明
时间敏感场景下,靠文件名推断内容时段不可靠,归档后务必用 zgrep 或 head -n1 确认首行时间戳。











