Linux logrotate 的 size vs daily 策略与 postrotate 脚本最佳实践

2次阅读

logrotate 的 size 和 daily 互斥,需据日志增长特性选择:daily 适合稳定日志按天归档,size 适合突发流量防单文件过大;postrotate 必须 reload 服务以确保写入新日志,不可省略。

Linux logrotate 的 size vs daily 策略与 postrotate 脚本最佳实践

logrotate 的 sizedaily 是两种互斥的轮转触发条件,不能同时生效;选择哪个取决于日志增长特性和运维目标。postrotate 脚本不是“可有可无”的附加项,而是确保服务持续写入新日志的关键环节,尤其在使用 copytruncate 之外的场景下必须正确 reload 或 reopen 日志句柄。

size vs daily:如何选?关键看日志写入节奏

daily 表示每天固定时间(默认由 cron 触发)检查并轮转,不管当天日志是否写满;size 则只关注单个日志文件体积,达到阈值立即轮转,与时间无关。二者不可共存——logrotate 遇到 size 就忽略 daily,反之亦然。

  • daily:适用于日志量稳定、按天归档便于审计或备份的场景(如 nginx access.log、系统 audit 日志);需配合 dateextdateformat 保证文件名可读
  • size:适用于突发流量导致日志暴增的服务(如调试中的应用、高频 API 网关);推荐设为 size 100Msize 500M,避免单文件过大影响 grep 或传输
  • 慎用 hourlyweekly:hourly 依赖 cron 每小时执行一次,但 logrotate 默认不自带 hourly 任务,需手动添加;weekly 可能导致周中日志积过多

postrotate 脚本必须做三件事:通知服务、验证成功、避免竞态

postrotate 执行时机是旧日志已重命名、新日志尚未创建时。此时若服务仍向原文件路径写入,就会写进已轮转的旧文件(除非用了 copytruncate),导致日志丢失。

  • 必须发送信号或调用 reload:例如 systemctl reload nginxkill -USR1 `cat /var/run/nginx.pid`/usr/bin/pkill -USR1 rsyslogd;不要用 restart,会中断服务
  • 加简单校验逻辑:比如轮转后 ls -l /var/log/nginx/access.log 应返回“no such file”,或检查 systemctl is-active nginx 是否仍为 active
  • 避免脚本失败导致后续轮转卡住:在 postrotate 开头加 set +e(允许错误继续),或用 || true 包裹非关键命令;但 reload 类操作失败应保留退出码,方便排查

常见陷阱与绕过方案

很多问题不是配置写错,而是没理解 logrotate 的执行上下文和权限模型。

  • 权限不足:logrotate 默认以 root 运行,但 postrotate 中调用的 reload 命令可能依赖用户环境变量(如 PATH);建议写绝对路径:/bin/systemctl reload nginx,而非仅 systemctl
  • copytruncate 不是万能解:它通过截断原文件实现“无感知”轮转,但存在微小窗口期——截断后、写入前,部分日志可能丢失;高可靠性场景仍应优先走 signal/reload 方式
  • 多个配置匹配同一文件:logrotate 按配置文件字典序加载,后加载的规则会覆盖先加载的;用 logrotate -d /etc/logrotate.conf 查看实际生效规则,确认无冲突

一个生产可用的 Nginx 示例

兼顾大小控制、时间归档和安全 reload:

/var/log/nginx/*.log {     size 200M     rotate 30     compress     delaycompress     missingok     notifempty     create 0644 www-data www-data     sharedscripts     postrotate         if systemctl is-active --quiet nginx; then             systemctl reload nginx 2>/dev/null || true         fi     endscript }

注意:这里用 size 主控,但保留 rotate 30 防止单日突增撑爆磁盘;sharedscripts 确保多个日志文件共用一个 postrotate,避免重复 reload。

text=ZqhQzanResources