持续监控指定 IP,连续丢包 5 次后自动发送邮件告警

Posted by he; tagged with none

Debian 系统持续监控指定 IP,连续丢包 5 次后自动发送邮件告警,并支持开机自启。

最终路径说明:
监控脚本:/ping/ping_monitor.sh
日志文件:/ping/ping_monitor.log
邮件封装脚本:/www/wwwroot/10.10.10.23/mail/send_alert.php

一、创建邮件封装脚本

在邮件目录下新建 send_alert.php(不修改原有的 send.php 和 Smtp.class.php):


/**
 * ping 监控告警专用邮件发送封装
 * 用法:php send_alert.php "收件人邮箱" "邮件标题" "邮件正文"
 * 不修改原有 send.php 和 Smtp.class.php
 */

if ($argc < 4) {
    fwrite(STDERR, "Usage: php send_alert.php 收件人邮箱 邮件标题 邮件正文\n");
    exit(1);
}

$email   = $argv[1];
$title   = $argv[2];
$content = $argv[3];
$attachments_c = [];

require __DIR__ . '/send.php';

if (isset($state) && $state) {
    exit(0);
} else {
    exit(1);
}

二、创建监控脚本

#!/bin/bash

# ==================== 配置区域 ====================
IP="10.10.10.1"                                          # 要监控的 IP(请修改)
THRESHOLD=5                                           # 连续丢包次数触发告警
INTERVAL=1                                            # ping 间隔(秒)
EMAIL_TO="heis999@qq.com"                        # 收件人邮箱(请修改)
EMAIL_SUBJECT="内网丢包 $IP 连续丢包"
LOG_FILE="/ping/ping_monitor.log"

# 邮件封装脚本路径
PHP_ALERT_SCRIPT="/www/wwwroot/10.10.10.23/mail/send_alert.php"

# 同一故障冷却时间(秒),避免重复发邮件
ALERT_COOLDOWN=300
# =================================================

consecutive_fail=0
last_alert_time=0

log() {
    echo "$(date '+%Y-%m-%d %H:%M:%S') $1" | tee -a "$LOG_FILE"
}

send_alert() {
    local msg="$1"
    local now=$(date +%s)

    if (( now - last_alert_time < ALERT_COOLDOWN )); then
        log "告警冷却中,跳过本次邮件"
        return
    fi

    log "准备发送告警邮件..."

    php "$PHP_ALERT_SCRIPT" "$EMAIL_TO" "$EMAIL_SUBJECT" "$msg"

    if [ $? -eq 0 ]; then
        log "邮件发送成功"
        last_alert_time=$now
    else
        log "邮件发送失败,请检查 PHP 脚本或 SMTP 配置"
    fi
}

# 确保日志目录存在
mkdir -p "$(dirname "$LOG_FILE")"

log "开始监控 $IP ,连续丢包阈值: $THRESHOLD"

while true; do
    if ping -c 1 -W 2 "$IP" > /dev/null 2>&1; then
        if [ $consecutive_fail -ge $THRESHOLD ]; then
            log "$IP 已恢复连通"
            # 如需恢复时也发邮件,取消下一行注释
            # send_alert "$IP 已恢复连通,之前连续丢包 $consecutive_fail 次"
        fi
        consecutive_fail=0
    else
        ((consecutive_fail++))
        log "丢包 ($consecutive_fail/$THRESHOLD)"

        if [ $consecutive_fail -eq $THRESHOLD ]; then
            send_alert "$IP 已连续丢包 $THRESHOLD 次,请检查网络!
时间: $(date)
主机: $(hostname)"
        fi
    fi

    sleep $INTERVAL
done

三、测试邮件是否能正常发送

php /www/wwwroot/10.10.10.23/mail/send_alert.php "你的邮箱@example.com" "测试标题" "这是一条测试内容"

四、配置 systemd 开机自启

cat > /etc/systemd/system/ping-monitor.service << 'EOF'
[Unit]
Description=Ping Continuous Monitor
After=network.target

[Service]
Type=simple
ExecStart=/ping/ping_monitor.sh
Restart=always
RestartSec=5
User=root

[Install]
WantedBy=multi-user.target
EOF

systemctl daemon-reload
systemctl enable --now ping-monitor.service
systemctl status ping-monitor.service

五、常用管理命令

# 实时查看日志
tail -f /ping/ping_monitor.log

# 查看服务状态
systemctl status ping-monitor.service

# 停止服务
systemctl stop ping-monitor.service

# 重启服务(修改脚本后执行)
systemctl restart ping-monitor.service

# 查看是否开机自启
systemctl is-enabled ping-monitor.service

修改监控 IP 或收件人邮箱后,记得执行 systemctl restart ping-monitor.service 使配置生效。

- 本文完 -