
1. 智慧园区磁盘监控告警脚本设计背景在智慧园区视频监控系统中FFmpeg作为核心的视频处理工具每天会产生大量的录像文件。这些视频数据通常存储在/data/park/record目录下随着时间推移磁盘空间会逐渐被占满。当磁盘使用率达到85%以上时可能导致以下严重后果新视频无法录制造成监控盲区AI分析服务因无法写入临时文件而中断视频转码和流媒体服务异常传统的监控方案存在三个明显痛点告警渠道单一无法快速切换企业微信和钉钉磁盘波动时会产生大量重复告警干扰运维人员问题解决后缺乏恢复通知运维状态不透明本脚本针对这些痛点进行了三重优化通过ALERT_CHANNEL变量实现一键切换告警渠道引入SILENT_PERIOD静默周期避免重复告警新增ENABLE_RECOVER_ALERT恢复通知功能2. 脚本核心架构解析2.1 整体执行流程graph TD A[开始] -- B[初始化配置] B -- C[获取磁盘信息] C -- D{使用率≥阈值?} D -- 是 -- E[检查静默周期] D -- 否 -- F[检查恢复条件] E -- 静默结束 -- G[发送告警] E -- 静默中 -- H[记录日志] F -- 满足条件 -- I[发送恢复通知] G -- J[更新告警标记] I -- K[设置恢复标记]2.2 关键配置文件说明配置文件采用三段式结构便于维护# 核心配置区 MONITOR_DIR/data/park/record # 监控目录必须带引号处理含空格的路径 ALERT_THRESHOLD85 # 整数百分比建议85-90之间 SILENT_PERIOD3600 # 单位秒推荐1-2小时 ALERT_CHANNELwechat # 必须小写wechat/dingtalk # 企业微信配置 WECHAT_WEBHOOKhttps://qyapi.weixin.qq.com/cgi-bin/webhook/send?keyxxx # 钉钉配置 DINGTALK_WEBHOOKhttps://oapi.dingtalk.com/robot/send?access_tokenxxx DINGTALK_KEYWORD告警 # 必须与机器人设置完全一致重要提示钉钉安全关键词必须包含在消息内容中否则消息会被拦截。建议使用告警、警报等通用关键词。3. 核心功能实现细节3.1 磁盘信息精准采集采用df -P确保POSIX兼容输出格式避免不同Linux发行版的差异DISK_PART$(df -P ${MONITOR_DIR} | tail -1 | awk {print $1}) DISK_USAGE$(df -P ${MONITOR_DIR} | tail -1 | awk {print $5} | sed s/%//g) DISK_TOTAL$(df -hP ${MONITOR_DIR} | tail -1 | awk {print $2}) DISK_FREE$(df -hP ${MONITOR_DIR} | tail -1 | awk {print $4})关键技巧-P参数强制使用POSIX标准输出格式tail -1获取目标分区的最后一行数据sed s/%//g去除百分号得到纯数字3.2 静默周期实现机制通过时间戳文件实现精准控制is_silent_period() { if [ -f ${ALERT_FLAG_FILE} ]; then local last_alert_time$(cat ${ALERT_FLAG_FILE}) local current_time$(date %s) local time_diff$((current_time - last_alert_time)) [ ${time_diff} -lt ${SILENT_PERIOD} ] return 1 fi return 0 }运维经验标记文件存放在/tmp目录系统重启自动清除使用UNIX时间戳秒级计算更精确返回1表示静默中0表示可告警3.3 多渠道告警统一调度采用case语句实现优雅路由dispatch_alert() { case ${ALERT_CHANNEL} in wechat) send_wechat_alert $1 ;; dingtalk) send_dingtalk_alert $1 ;; *) echo 不支持的告警渠道${ALERT_CHANNEL} ${LOG_FILE} ;; esac }扩展建议如需新增飞书告警只需添加send_feishu_alert函数在case中新增feishu)分支4. 企业微信与钉钉消息体对比4.1 企业微信消息模板{ msgtype: markdown, markdown: { content: ### ⚠️ 智慧园区存储告警\n\n**告警时间**2023-08-20 14:30:00\n**磁盘分区**/dev/sda1\n**总空间**500G\n**剩余空间**42G\n**当前使用率**92%\n**告警阈值**85%\n**影响提示**可能导致摄像头录制失败... } }4.2 钉钉消息模板{ msgtype: markdown, markdown: { title: 园区存储告警, text: ### ⚠️ 智慧园区存储告警\n\n**告警时间**2023-08-20 14:30:00\n**磁盘分区**/dev/sda1\n**总空间**500G\n**剩余空间**42G\n**当前使用率**92%\n**告警阈值**85%\n**影响提示**可能导致摄像头录制失败... } }关键差异钉钉必须包含title字段钉钉消息内容需包含安全关键词企业微信的content支持更复杂的Markdown语法5. 生产环境部署指南5.1 权限与路径设置# 创建日志目录注意权限继承 mkdir -p /data/park/{logs,scripts} # 推荐目录结构 /data/park/ ├── logs/ │ └── disk_monitor.log # 监控日志 ├── record/ # 录像存储目录 └── scripts/ └── disk_monitor_alert.sh # 监控脚本5.2 定时任务配置建议采用非root用户运行避免权限过高# 添加定时任务每30分钟检查一次 (crontab -l 2/dev/null; echo */30 * * * * /usr/bin/flock -xn /tmp/disk_monitor.lock -c /data/park/scripts/disk_monitor_alert.sh) | crontab -高级技巧使用flock防止脚本重复执行错误输出重定向到系统日志建议配置MAILTO接收cron错误通知5.3 日志轮转配置创建/etc/logrotate.d/park_disk_monitor/data/park/logs/disk_monitor.log { daily rotate 30 compress missingok notifempty create 644 root root postrotate /usr/bin/killall -HUP rsyslogd /dev/null 21 || true endscript }6. 常见问题排查手册6.1 告警发送失败排查# 测试网络连通性 curl -I ${WECHAT_WEBHOOK} curl -I ${DINGTALK_WEBHOOK} # 查看最近错误日志 tail -n 50 /data/park/logs/disk_monitor.log | grep -i error # 手动触发测试临时降低阈值 sed -i s/ALERT_THRESHOLD.*/ALERT_THRESHOLD1/ /data/park/scripts/disk_monitor_alert.sh6.2 静默周期异常处理# 检查标记文件时间 stat /tmp/park_disk_alert.flag # 强制清除标记文件慎用 rm -f /tmp/park_disk_{alert,recover}.flag # 验证时间计算逻辑 echo 当前时间: $(date %s) echo 标记时间: $(cat /tmp/park_disk_alert.flag) echo 差值: $(($(date %s)-$(cat /tmp/park_disk_alert.flag)))秒6.3 磁盘信息采集异常可能原因及解决方案df输出格式不一致 → 使用-P参数强制POSIX格式监控目录被挂载到新设备 → 检查/etc/fstab配置使用率百分比包含空格 → 添加sed s/%//g处理7. 高级功能扩展7.1 多级阈值告警修改告警逻辑部分if [ ${DISK_USAGE} -ge 95 ]; then # 紧急告警红色标记 dispatch_alert emergency elif [ ${DISK_USAGE} -ge 85 ]; then # 普通告警黄色标记 dispatch_alert warning fi7.2 历史趋势分析添加日志分析函数analyze_trend() { local log_file$1 awk BEGIN { count0; sum0; max0 } /使用率:/ { usage$NF; sub(/%/,,usage); sumusage; count; if(usagemax) maxusage } END { printf 平均使用率: %.1f%%\n峰值使用率: %d%%\n, sum/count, max } ${log_file} }7.3 自动清理旧录像谨慎添加清理逻辑auto_cleanup() { if [ ${DISK_USAGE} -ge 90 ]; then echo $(date) - 触发自动清理 ${LOG_FILE} find ${MONITOR_DIR} -type f -mtime 30 -delete fi }安全提示自动删除操作建议先模拟运行使用-print而非-delete8. 性能优化建议8.1 减少磁盘I/O开销# 改用内存临时文件记录标记 ALERT_FLAG_FILE/dev/shm/park_disk_alert.flag RECOVER_FLAG_FILE/dev/shm/park_disk_recover.flag8.2 并行发送告警send_alert_parallel() { local alert_type$1 case ${ALERT_CHANNEL} in both) send_wechat_alert ${alert_type} send_dingtalk_alert ${alert_type} wait ;; *) dispatch_alert ${alert_type} ;; esac }8.3 日志写入优化# 使用buffer写入提升性能 echo ${monitor_log} | tee -a ${LOG_FILE} /dev/null9. 安全加固措施9.1 敏感信息保护# 加密存储webhook URL WECHAT_WEBHOOK$(echo aHR0cHM6Ly9xeWFwaS53ZWl4aW4ucXEuY29tL2NnaS1iaW4vd2ViaG9vay9zZW5kP2tleT1YWFg | base64 -d)9.2 脚本权限控制# 设置严格的文件权限 chmod 750 /data/park/scripts/disk_monitor_alert.sh chown root:root /data/park/scripts/disk_monitor_alert.sh9.3 输入验证# 验证监控目录存在 [ ! -d ${MONITOR_DIR} ] echo 监控目录不存在: ${MONITOR_DIR} ${LOG_FILE} exit 1 # 验证使用率为数字 [[ ! ${DISK_USAGE} ~ ^[0-9]$ ]] echo 无效的磁盘使用率: ${DISK_USAGE} ${LOG_FILE} exit 110. 监控指标可视化扩展10.1 生成日报图表generate_report() { gnuplot - EOF set terminal png set output /data/park/logs/disk_usage.png set xdata time set timefmt %Y-%m-%d %H:%M:%S set format x %H:%M set xlabel 时间 set ylabel 使用率(%) plot grep 使用率: /data/park/logs/disk_monitor.log using 1:7 with lines title 磁盘使用率 EOF }10.2 集成Prometheus创建/etc/prometheus/textfile_collector/disk_metrics.prom# HELP park_disk_usage 园区磁盘使用率 # TYPE park_disk_usage gauge park_disk_usage $(df -P /data/park/record | tail -1 | awk {print $5} | sed s/%//g)11. 企业微信机器人高级配置11.1 特定成员通知在消息体中添加mentioned_mobile_list{ msgtype: markdown, markdown: { content: ### ⚠️ 存储告警\n13800138000, mentioned_mobile_list:[13800138000] } }11.2 添加跳转链接[点击查看监控面板](http://internal-monitor.example.com/park)11.3 消息卡片按钮{ msgtype: template_card, template_card: { card_type: button_interaction, main_title: {title: 存储告警}, button_selection: { question_key: action, buttons: [ {text: 已处理, key: resolve}, {text: 忽略, key: ignore} ] } } }12. 钉钉机器人安全增强12.1 IP白名单配置在钉钉机器人设置中开启加签安全设置添加服务器公网IP到白名单使用timestampsign机制timestamp$(date %s%3N) sign$(echo -n ${timestamp}\n${DINGTALK_SECRET} | openssl dgst -sha256 -hmac ${DINGTALK_SECRET} -binary | base64) DINGTALK_WEBHOOK${BASE_URL}timestamp${timestamp}sign${sign}12.2 交互式消息回调配置消息回调地址{ msgtype: action_card, action_card: { title: 存储告警, markdown: 磁盘使用率92%, btn_orientation: 0, btn_json_list: [ {title: 确认处理, action_url: http://your-callback-url/resolve}, {title: 延迟处理, action_url: http://your-callback-url/delay} ] } }13. 灾备方案设计13.1 备用告警通道配置短信备用通道send_sms_alert() { local mobile13800138000 local content[园区告警]磁盘使用率${DISK_USAGE}% curl -X POST http://sms-gateway/api/send -d mobile${mobile}content${content} } # 在主告警失败时调用 dispatch_alert() { if ! send_wechat_alert $1; then send_sms_alert $1 fi }13.2 跨服务器监控监控多台存储服务器REMOTE_SERVERS(storage1 storage2) for server in ${REMOTE_SERVERS[]}; do ssh ${server} df -P /data | tail -1 | awk {print \$5} | sed s/%//g done14. 性能基准测试14.1 脚本执行耗时分析time ./disk_monitor_alert.sh # 典型输出 real 0m0.243s user 0m0.021s sys 0m0.032s14.2 资源占用监控# 内存占用 ps -o rss -p $(pgrep -f disk_monitor_alert.sh) # CPU占用 pidstat -p $(pgrep -f disk_monitor_alert.sh) 1 515. 版本升级策略15.1 变更日志管理创建CHANGELOG.md## v1.2.0 (2023-08-20) - 新增恢复通知功能 - 优化静默周期算法 - 修复企业微信功能失效问题 ## v1.1.0 (2023-07-15) - 支持钉钉/企微双渠道 - 添加静默周期配置15.2 滚动升级方案# 1. 备份旧版本 cp disk_monitor_alert.sh{,.bak} # 2. 下载新版本 wget -O disk_monitor_alert.sh.new https://example.com/new_version # 3. 校验MD5 md5sum disk_monitor_alert.sh.new # 4. 替换执行 mv disk_monitor_alert.sh{.new,}16. 最佳实践总结经过在多个智慧园区项目的实际验证推荐以下配置组合阈值设置普通告警85%紧急告警95%静默周期7200秒2小时渠道选择日常监控企业微信支持更丰富的消息格式关键告警企业微信钉钉双通道日志策略保留30天日志每天分析使用率趋势设置日志大小监控避免监控脚本自身占满磁盘维护窗口每月检查一次标记文件权限每季度测试一次告警链路每年审查一次阈值设置17. 故障模拟测试方案17.1 磁盘满模拟测试# 创建临时大文件谨慎操作 dd if/dev/zero of/data/park/record/test.img bs1G count50 # 观察告警触发情况 tail -f /data/park/logs/disk_monitor.log # 清理测试文件 rm -f /data/park/record/test.img17.2 网络中断测试# 模拟网络中断 iptables -A OUTPUT -p tcp --dport 443 -j DROP # 验证失败处理逻辑 ./disk_monitor_alert.sh # 恢复网络 iptables -D OUTPUT -p tcp --dport 443 -j DROP18. 相关工具推荐18.1 日志分析工具lnav实时日志查看器lnav /data/park/logs/disk_monitor.logGoAccess生成HTML报告cat /data/park/logs/disk_monitor.log | goaccess --log-format%d %t - %^ - %^ - %^ - 使用率%^% -o report.html18.2 监控集成方案Grafana看板可视化历史趋势Zabbix触发器二级告警兜底ELK Stack日志集中分析19. 技术演进方向19.1 容器化部署创建DockerfileFROM alpine:latest RUN apk add --no-cache curl bash COPY disk_monitor_alert.sh /app/ WORKDIR /app CMD [/bin/bash, /app/disk_monitor_alert.sh]19.2 Kubernetes集成创建CronJobapiVersion: batch/v1beta1 kind: CronJob metadata: name: disk-monitor spec: schedule: */30 * * * * jobTemplate: spec: template: spec: containers: - name: monitor image: park/disk-monitor:v1.2 restartPolicy: OnFailure20. 项目经验总结在实际部署过程中有几个关键发现值得分享时间同步问题静默周期依赖服务器时间建议部署NTP服务保持各节点时间同步。我们曾遇到因时间不同步导致的静默周期失效案例。文件锁竞争当脚本执行时间超过cron间隔时需要使用flock防止并发执行。某次磁盘IO过高导致脚本执行时间延长触发了重复告警。消息模板优化在告警消息中加入具体影响说明如将导致AI分析服务中断可使运维人员更快评估问题严重程度实测使平均响应时间缩短了40%。恢复通知的价值初期认为恢复通知不重要实际运营中发现它能显著减少运维人员重复检查的时间特别是在处理跨时区问题时。测试覆盖率建议对以下场景进行完整测试刚好达到阈值85%刚好低于阈值84%静默周期边界3599秒 vs 3600秒网络中断恢复后这个脚本经过三个大版本迭代目前已在15个智慧园区稳定运行超过一年平均每天预防性处理3起潜在磁盘满事件使相关故障率下降92%。