如何实现Cron Job/脚本监控 故障自动重启及日志关键词告警?
完全可以搭建这套监控机制,不需要依赖重型商用监控平台,不管是轻量自研脚本还是成熟开源技术栈都能落地,整套机制拆成四个核心模块即可实现:
核心模块设计
- 状态采集层:同时覆盖Cron调度状态、运行中脚本的存活状态两类监测对象
- 针对Cron Job:直接读取系统对应日志(CentOS/RHEL系读
/var/log/cron,Debian/Ubuntu系读/var/log/syslog)核对任务是否按预期时间触发;同时给所有被监控脚本加上启动、退出打点,启动时将带时间戳、进程PID的记录写入指定状态文件,正常退出时写入退出码0的标记。 - 针对常驻运行脚本:通过校验进程PID存活、核对脚本自带的健康检查接口返回结果两种方式,判断脚本是否处于正常运行状态。
- 针对Cron Job:直接读取系统对应日志(CentOS/RHEL系读
- 故障判定层:支持日志关键词匹配+通用异常规则双重校验,避免漏判误判
- 给每个被监控对象配置独立规则文件,可自定义需要识别的异常关键词列表,比如
error、fatal、connection refused以及业务专属错误标识,实时监听脚本输出的日志文件,匹配到预设关键词即纳入异常判断。 - 补充通用异常判定规则:脚本退出码非0、Cron任务到点未触发、常驻脚本进程消失、脚本运行时长超过预设阈值,都直接判定为异常。
建议给关键词匹配加防抖逻辑,比如连续3次匹配到异常关键词才正式判定故障,避免日志中偶发的无关错误触发误告警。
- 给每个被监控对象配置独立规则文件,可自定义需要识别的异常关键词列表,比如
- 自动处置层:故障判定后第一时间执行自动恢复
- 按照预先配置的映射关系,先清理故障脚本的残留进程(避免端口占用、文件锁残留导致重启失败),再执行预设启动命令拉起脚本,所有操作的时间、故障原因都要写入本地操作日志留痕。
- 给重启操作加冷却限制:比如10分钟内同一个脚本连续重启超过3次就停止自动重启,避免脚本存在硬错误时反复重启占用系统资源。
- 告警通知层:全流程节点都要触达相关责任人
- 可对接企业微信、钉钉、邮件等常用通知渠道,告警内容需要明确包含:故障脚本名称、故障触发时间、故障原因(进程消失/匹配到的具体异常关键词/退出码异常等)、自动重启操作的执行结果。
- 对连续重启失败的故障升级告警频次,比如从15分钟推送一次改成5分钟推送一次,直到人工介入处理。
轻量实现参考(无额外依赖,基于Shell)
如果监控的脚本数量不多,不需要搭复杂的监控栈,几十行Shell就能实现基础能力,比如要监控的业务脚本路径为/opt/run_biz.sh,日志输出到/var/log/biz.log,异常关键词设为fatal、timeout:
- 编写监控脚本
/opt/monitor_biz.sh
#!/bin/bash # 基础配置 SCRIPT_PATH="/opt/run_biz.sh" LOG_PATH="/var/log/biz.log" ERROR_KEYWORDS=("fatal" "timeout") MAX_RESTART=3 RESTART_COOLDOWN=600 ALERT_TARGET="dev-ops-group" # 进程存活校验 check_process_alive() { pidof -o %PPID -x "$(basename $SCRIPT_PATH)" >/dev/null return $? } # 日志异常关键词校验 check_log_error() { tail -n 200 $LOG_PATH | grep -E "$(IFS="|"; echo "${ERROR_KEYWORDS[*]}")" >/dev/null return $? } # 脚本重启逻辑 do_restart() { pkill -f "$(basename $SCRIPT_PATH)" sleep 2 nohup $SCRIPT_PATH >> $LOG_PATH 2>&1 & } # 主判断逻辑 if ! check_process_alive || check_log_error; then restart_count=$(cat /tmp/biz_restart_cnt 2>/dev/null || echo 0) last_restart_ts=$(cat /tmp/biz_last_restart_ts 2>/dev/null || echo 0) current_ts=$(date +%s) # 超过冷却时间重置计数 if [ $((current_ts - last_restart_ts)) -gt $RESTART_COOLDOWN ]; then restart_count=0 fi if [ $restart_count -lt $MAX_RESTART ]; then do_restart echo $((restart_count+1)) > /tmp/biz_restart_cnt echo $current_ts > /tmp/biz_last_restart_ts # 替换为实际可用的告警发送命令 echo "[$(date)] 脚本${SCRIPT_PATH}触发故障,已执行自动重启,近10分钟累计重启次数:$((restart_count+1))" | mail -s "脚本故障告警" $ALERT_TARGET else echo "[$(date)] 脚本${SCRIPT_PATH}近10分钟重启次数超限,已停止自动重启,请人工排查" | mail -s "脚本故障升级告警" $ALERT_TARGET fi fi
- 将监控脚本加入系统Cron,每分钟执行一次即可完成基础监控:
* * * * * /bin/bash /opt/monitor_biz.sh
如果需要管理的脚本规模较大(几十上百个节点/任务),可以替换为成熟开源方案:用systemd托管常驻脚本实现退出自动重启,用Prometheus做状态指标采集,用Loki/Promtail配置日志关键词匹配规则,配合Alertmanager实现告警分发,核心逻辑和上述轻量脚本完全一致,只是大规模场景下运维效率更高。
内容的提问来源于stack exchange,提问作者MazaherM
相关产品推荐
相关产品推荐

