<p>每5分钟检查日志大小需用/5 *而非“每5分钟”,脚本中须用绝对路径、捕获stderr、统一单位、避免logrotate冲突,并注意权限与环境差异。</p>

用crontab设置每5分钟执行日志大小检查
直接在用户或系统级crontab里添加一行,就能实现固定间隔检查。关键是时间表达式别写错,*/5 * * * * 表示“每小时的第0、5、10…55分钟各执行一次”,不是“从现在起每5分钟”,这点很多人混淆。
- 编辑当前用户crontab:
crontab -e,追加一行:*/5 * * * * /usr/bin/du -h /var/log/syslog | /usr/bin/awk '{print $1}' >> /tmp/logsize.log 2>&1 - 如果要检查多个日志文件,建议封装成脚本再调用,避免crontab行内逻辑过长导致解析失败
- 注意路径必须用绝对路径——crontab默认
$PATH极简,du、awk不加/usr/bin/前缀很可能报command not found - 重定向
2>&1不能省,否则错误(比如文件被轮转删除)会静默丢失,查问题时无迹可寻
用shell脚本判断日志是否超限并告警
单纯看大小没意义,得配合阈值做决策。常见做法是用stat或du取大小,再用-gt比较,但要注意单位统一。
-
du -b输出字节数,适合数值比较;du -h人类可读,但不能直接用于if [ $size -gt 104857600 ]这种判断 - 检查
/var/log/messages是否超过100MB示例:#!/bin/bash SIZE=$(du -b /var/log/messages 2>/dev/null | cut -f1) if [ "$SIZE" -gt 104857600 ] 2>/dev/null; then logger "ALERT: /var/log/messages > 100MB ($SIZE bytes)" # 可在此加入发邮件、调用webhook等动作 fi - 务必加
2>/dev/null抑制du对已删除或权限不足文件的报错,否则cron日志刷屏 - 脚本开头加
#!/bin/bash,且crontab中调用时用/bin/bash /path/to/check.sh,别依赖sh兼容性
避免日志检查干扰logrotate正常工作
logrotate运行期间可能临时重命名、压缩或清空日志,此时直接du原文件会失败或返回0,不是bug,是竞态。
- 不要在logrotate配置的
postrotate里反向触发检查脚本,容易形成循环或时序混乱 - 若需精确监控“活跃日志体积”,优先检查未被rotate的当前文件,用
ls -t /var/log/*.log | head -1找最新文件,比硬编码路径更健壮 - logrotate默认每天执行,而你的5分钟检查可能刚巧撞上rotate瞬间,
stat -c "%s" file比du更快、更轻量,也更少受锁影响
权限与日志路径的常见坑
非root用户无法读/var/log/secure这类文件,crontab里用普通用户跑会默默失败。
- 检查目标日志权限:
ls -l /var/log/your.log,若属主是root:syslog,要么改crontab为root运行(sudo crontab -e),要么给用户加read权限(不推荐)或加到syslog组 - systemd-journald管理的日志(如
/run/log/journal)不能用du直接扫,得用journalctl --disk-usage - 容器环境日志常挂载在
/var/lib/docker/containers/xxx/xxx-json.log,路径动态生成,需先用docker ps或find定位,不能写死
实际部署时,最易忽略的是stderr捕获和权限上下文切换——cron环境和交互shell差太多,光看脚本能跑通不等于定时能跑通。


















