Shell脚本如何配置邮件报警功能

wen 实用脚本 1

本文目录导读:

Shell脚本如何配置邮件报警功能

  1. 安装邮件工具
  2. 配置邮件发送
  3. 基础邮件报警脚本
  4. 完整的监控报警脚本
  5. 高级报警功能
  6. 使用第三方邮件服务
  7. 注意事项

我来详细说明Shell脚本配置邮件报警的几种常用方法。

安装邮件工具

Ubuntu/Debian系统

# 安装mailutils和sendmail
sudo apt-get install mailutils sendmail sendmail-cf
# 或者使用heirloom-mailx
sudo apt-get install heirloom-mailx
# 配置Postfix(如需发送外部邮件)
sudo apt-get install postfix

CentOS/RHEL系统

# 安装mailx
sudo yum install mailx
# 安装sendmail
sudo yum install sendmail sendmail-cf

配置邮件发送

使用本地Sendmail(最简单的配置)

# 启动sendmail服务
sudo systemctl start sendmail
sudo systemctl enable sendmail

使用外部SMTP服务器(如QQ邮箱、163邮箱等)

创建配置文件 ~/.mailrc/etc/mail.rc

# QQ邮箱示例
set from=yourname@qq.com
set smtp=smtp.qq.com
set smtp-auth-user=yourname@qq.com
set smtp-auth-password=your-auth-code  # QQ邮箱使用授权码
set smtp-auth=login
set ssl-verify=ignore

基础邮件报警脚本

简单的邮件发送函数

#!/bin/bash
# 邮件配置
TO_EMAIL="admin@example.com"
FROM_EMAIL="monitor@example.com"
SUBJECT_PREFIX="[服务器报警]"
# 发送邮件函数
send_email() {
    local subject="$1"
    local body="$2"
    echo "$body" | mail -s "${SUBJECT_PREFIX}${subject}" "$TO_EMAIL"
}
# 使用示例
send_email "CPU使用率过高" "警告:CPU使用率已超过90%"

带附件的邮件发送

#!/bin/bash
send_email_with_attachment() {
    local subject="$1"
    local body="$2"
    local attachment="$3"
    # 使用mutt发送带附件的邮件
    echo "$body" | mutt -s "${SUBJECT_PREFIX}${subject}" \
        -a "$attachment" -- "$TO_EMAIL"
    # 或者使用mailx
    # echo "$body" | mailx -s "${SUBJECT_PREFIX}${subject}" \
    #     -A "$attachment" "$TO_EMAIL"
}

完整的监控报警脚本

#!/bin/bash
# ==================== 配置区域 ====================
ADMIN_EMAIL="admin@example.com"
HOSTNAME=$(hostname)
LOG_FILE="/var/log/monitor_alerts.log"
# 阈值配置
CPU_THRESHOLD=80
MEM_THRESHOLD=90
DISK_THRESHOLD=85
LOAD_THRESHOLD=5
# ==================== 函数定义 ====================
# 日志记录
log_message() {
    local level="$1"
    local message="$2"
    echo "[$(date '+%Y-%m-%d %H:%M:%S')] [$level] $message" >> "$LOG_FILE"
}
# 发送报警邮件
send_alert() {
    local alert_type="$1"
    local alert_value="$2"
    local alert_message="$3"
    # 构建邮件内容
    local subject="[${HOSTNAME}] ${alert_type} 异常警报"
    local body="
===== 服务器报警通知 =====
服务器:${HOSTNAME}
时间:$(date '+%Y-%m-%d %H:%M:%S')
报警类型:${alert_type}
当前值:${alert_value}
详细信息:
${alert_message}
===============================
"
    # 发送邮件
    echo "$body" | mail -s "$subject" "$ADMIN_EMAIL"
    # 记录日志
    log_message "ALERT" "$alert_type: $alert_value - $alert_message"
}
# 检查CPU使用率
check_cpu() {
    local cpu_usage=$(top -bn1 | grep "Cpu(s)" | awk '{print $2}' | cut -d'%' -f1)
    if (( $(echo "$cpu_usage > $CPU_THRESHOLD" | bc -l) )); then
        send_alert "CPU使用率" "${cpu_usage}%" \
            "CPU使用率 ${cpu_usage}% 超过阈值 ${CPU_THRESHOLD}%"
        return 1
    fi
    log_message "INFO" "CPU使用率正常: ${cpu_usage}%"
    return 0
}
# 检查内存使用率
check_memory() {
    local mem_usage=$(free | grep Mem | awk '{print $3/$2 * 100.0}')
    if (( $(echo "$mem_usage > $MEM_THRESHOLD" | bc -l) )); then
        send_alert "内存使用率" "${mem_usage}%" \
            "内存使用率 ${mem_usage}% 超过阈值 ${MEM_THRESHOLD}%"
        return 1
    fi
    log_message "INFO" "内存使用率正常: ${mem_usage}%"
    return 0
}
# 检查磁盘使用率
check_disk() {
    # 检查所有挂载点
    df -h | grep -vE '^Filesystem' | awk '{print $5 " " $6}' | while read -r output; do
        local usage=$(echo "$output" | awk '{print $1}' | cut -d'%' -f1)
        local partition=$(echo "$output" | awk '{print $2}')
        if [ "$usage" -ge "$DISK_THRESHOLD" ]; then
            send_alert "磁盘使用率" "${usage}%" \
                "分区 ${partition} 使用率 ${usage}% 超过阈值 ${DISK_THRESHOLD}%"
        fi
    done
}
# 检查系统负载
check_load() {
    local load=$(uptime | awk -F'[a-z]:' '{print $2}' | awk '{print $1}' | tr -d ',')
    if (( $(echo "$load > $LOAD_THRESHOLD" | bc -l) )); then
        send_alert "系统负载" "${load}" \
            "系统负载 ${load} 超过阈值 ${LOAD_THRESHOLD}"
        return 1
    fi
    log_message "INFO" "系统负载正常: ${load}"
    return 0
}
# 检查特定进程是否运行
check_process() {
    local process_name="$1"
    if ! pgrep -x "$process_name" > /dev/null; then
        send_alert "进程异常" "${process_name}" \
            "关键进程 ${process_name} 未运行,请立即检查!"
        # 尝试重启进程
        systemctl start "$process_name" 2>/dev/null || \
            service "$process_name" start 2>/dev/null
        log_message "WARN" "尝试重启进程: ${process_name}"
    else
        log_message "INFO" "进程运行正常: ${process_name}"
    fi
}
# 检查网络连接
check_network() {
    local target_host="$1"
    if ping -c 3 -W 5 "$target_host" > /dev/null 2>&1; then
        log_message "INFO" "网络连接正常: ${target_host}"
        return 0
    else
        send_alert "网络异常" "${target_host}" \
            "无法连接到 ${target_host},网络可能存在问题"
        return 1
    fi
}
# ==================== 主程序 ====================
main() {
    echo "开始系统监控检查..."
    log_message "INFO" "开始监控检查"
    # 执行各项检查
    check_cpu
    check_memory
    check_disk
    check_load
    # 检查关键进程
    check_process "nginx"
    check_process "mysql"
    check_process "sshd"
    # 检查网络连接
    check_network "8.8.8.8"
    check_network "www.baidu.com"
    echo "监控检查完成"
    log_message "INFO" "监控检查完成"
}
# 执行主程序
main

高级报警功能

带错误级别和告警抑制

#!/bin/bash
# 告警级别
ALERT_LEVELS=("INFO" "WARNING" "CRITICAL")
# 告警抑制(防止重复报警)
declare -A ALERT_CACHE
SUPPRESS_INTERVAL=300  # 5分钟内不重复告警
can_send_alert() {
    local alert_key="$1"
    local current_time=$(date +%s)
    if [[ -n "${ALERT_CACHE[$alert_key]}" ]]; then
        local last_time=${ALERT_CACHE[$alert_key]}
        local time_diff=$((current_time - last_time))
        if (( time_diff < SUPPRESS_INTERVAL )); then
            return 1  # 在抑制时间内,不发送
        fi
    fi
    # 更新时间
    ALERT_CACHE[$alert_key]=$current_time
    return 0  # 可以发送
}
# HTML格式邮件
send_html_email() {
    local to="$1"
    local subject="$2"
    local html_content="$3"
    # 使用mutt发送HTML邮件
    echo "$html_content" | mutt -e "my_hdr Content-Type: text/html" \
        -s "$subject" "$to"
}

定时执行(crontab配置)

# 编辑crontab
crontab -e
# 添加定时任务
# 每5分钟检查一次
*/5 * * * * /path/to/monitor.sh
# 每小时检查一次
0 * * * * /path/to/monitor.sh
# 每天凌晨2点发送日报
0 2 * * * /path/to/daily_report.sh

使用第三方邮件服务

使用sendEmail工具(更简单)

# 安装sendEmail
sudo apt-get install sendemail
# 发送邮件示例
sendEmail -f sender@example.com \
    -t receiver@example.com \
    -u "邮件主题" \
    -m "邮件内容" \
    -s smtp.example.com:587 \
    -o tls=yes \
    -xu sender@example.com \
    -xp "password"

使用curl发送(支持多种API)

#!/bin/bash
# SendGrid示例
send_sendgrid_email() {
    local api_key="YOUR_SENDGRID_API_KEY"
    local to_email="$1"
    local subject="$2"
    local content="$3"
    curl --request POST \
        --url https://api.sendgrid.com/v3/mail/send \
        --header "Authorization: Bearer $api_key" \
        --header "Content-Type: application/json" \
        --data "{
            \"personalizations\": [{\"to\": [{\"email\": \"$to_email\"}]}],
            \"from\": {\"email\": \"monitor@yourdomain.com\"},
            \"subject\": \"$subject\",
            \"content\": [{\"type\": \"text/plain\", \"value\": \"$content\"}]
        }"
}

注意事项

  1. 安全性:不要在脚本中硬编码密码,使用配置文件或环境变量
  2. 日志记录:记录所有报警动作,便于追踪
  3. 告警抑制:避免短时间内重复报警
  4. 测试验证:上线前充分测试邮件发送功能
  5. 备用方案:配置多个收件人,主备切换

这样配置后,你的Shell脚本就具备了完整的邮件报警功能了。

抱歉,评论功能暂时关闭!