You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

Shell脚本中实现信号量机制以避免同一问题重复发送告警

嘿,这个重复告警的问题我太熟了!很多人写监控脚本都会踩这个坑——只要阈值还超标就不停发邮件,邮箱直接炸掉对吧?其实用个简单的锁文件当信号量就能完美解决,下面给你一套落地性极强的方案:

用信号量(锁文件)阻止重复告警的Shell脚本方案

核心逻辑

本质就是用一个临时文件作为"告警标记":

  • 首次触发告警时,发送邮件并创建这个标记文件
  • 后续检测到阈值超标但标记存在时,直接跳过邮件发送
  • 当警告数回落至正常范围,立刻删除标记,恢复告警能力

完整可运行脚本示例

#!/bin/bash

# -------------------------- 配置区 --------------------------
LOG_FILE="/var/log/your_app.log"       # 要监控的日志文件路径
WARNING_THRESHOLD=10                   # 警告数量阈值
ALERT_EMAIL="ops_team@your_company.com"# 告警接收邮箱
LOCK_FILE="/tmp/app_warning_alert.lock"# 信号量锁文件路径
# -----------------------------------------------------------

# 统计日志中的警告数量(这里假设日志行含"WARNING"关键词,可按需修改)
warning_count=$(grep -c "WARNING" "$LOG_FILE")

# 先处理锁文件超时问题(防止脚本意外中断导致永久锁死)
if [ -f "$LOCK_FILE" ]; then
    # 计算锁文件存在时长(单位:秒),超过24小时自动清除
    lock_exist_time=$(( $(date +%s) - $(stat -c %Y "$LOCK_FILE") ))
    if [ "$lock_exist_time" -gt 86400 ]; then
        rm -f "$LOCK_FILE"
        echo "$(date +'%Y-%m-%d %H:%M:%S') - 锁文件已超时,自动清除"
    fi
fi

# 核心告警逻辑
if [ "$warning_count" -gt "$WARNING_THRESHOLD" ]; then
    if [ ! -f "$LOCK_FILE" ]; then
        # 发送告警邮件(这里用mail命令,可替换为sendmail或第三方邮件API)
        echo "系统告警:日志中警告数量超标!当前数量:$warning_count
        日志路径:$LOG_FILE
        阈值:$WARNING_THRESHOLD" | mail -s "【紧急告警】应用警告数量超出阈值" "$ALERT_EMAIL"
        
        # 创建锁文件标记已告警
        touch "$LOCK_FILE"
        echo "$(date +'%Y-%m-%d %H:%M:%S') - 警告数量超标,已发送告警并创建锁文件"
    else
        echo "$(date +'%Y-%m-%d %H:%M:%S') - 警告数量仍超标,但已发送过告警,跳过重复通知"
    fi
else
    # 警告数恢复正常,清除锁文件
    if [ -f "$LOCK_FILE" ]; then
        rm -f "$LOCK_FILE"
        echo "$(date +'%Y-%m-%d %H:%M:%S') - 警告数量恢复正常,已清除锁文件"
    fi
    echo "$(date +'%Y-%m-%d %H:%M:%S') - 警告数量在阈值范围内,无需处理"
fi

关键细节说明

  • 锁文件位置:选/tmp目录很合适,系统重启后会自动清理,避免遗留无效锁
  • 日志统计适配:如果你的日志格式特殊(比如需要按时间段统计),可以把grep -c "WARNING"换成awk或者sed的复杂过滤逻辑
  • 死锁防护:加了24小时超时清除逻辑,就算脚本意外崩溃,也不会永久无法触发新告警
  • 多指标扩展:如果要监控多个告警项,给每个项单独建锁文件即可(比如/tmp/alert_lock_error.tmp

部署建议

把脚本放到服务器上,用cron定时执行(比如每分钟跑一次):

# 编辑crontab
crontab -e
# 添加一行
* * * * * /path/to/your/alert_script.sh >> /var/log/alert_script_run.log 2>&1

内容的提问来源于stack exchange,提问作者sangavis

火山引擎 最新活动