背景:
多个系统部署在多个ECS(Linux)服务器上,每次巡检或者日常管理都是大问题。而且还比较滞后,都是问题出现了,才去排查。所以,高级的管理应主动发现异常,提早介入,将风险扼杀在摇篮中。
思路:
1、制定系统经常监控的指标信息(CPU、内存、磁盘、登录失败等)。
2、设置告警阈值,当高于设置的阈值,既触发。
3、触发机制,定时执行触发。
4、执行结果保存在日志文件。
5、邮件通知异常信息。
6、根据异常告警邮件,及时上去干预处理(可分析4,看出问题发生的时间点或时间段)。
开干:
创建可执行文件 system_monitor.sh
#!/bin/bash # 系统监控告警脚本 # 检测CPU、内存、磁盘使用率,以及*分钟内登录失败次数,超过阈值时发送邮件告警 # 配置参数 CPU_THRESHOLD=85 # CPU使用率阈值(%) MEM_THRESHOLD=80 # 内存使用率阈值(%) DISK_THRESHOLD=80 # 磁盘使用率阈值(%) LOGIN_FAIL_THRESHOLD=5 # 登录失败次数阈值 #TIME_WINDOW=5 # 时间窗口(分钟) EMAIL="*****@qq.com" # 告警接收邮箱 SUBJECT="系统资源告警 - $(hostname)" LOG_FILE="/data/script/monitor/logs/$(hostname)_$(date +%Y%m%d)_sys.out" # 同时输出到屏幕和日志 log() { local msg="[$(date '+%Y-%m-%d %H:%M:%S')]$1" echo "$msg" | tee -a "$LOG_FILE" } send_email() { printf "%s\n" "$2" | /usr/bin/mail -s "$1" "$EMAIL" log "[邮件发送] $1" } check_cpu() { echo "--- CPU 检查 ---" | tee -a "$LOG_FILE" local cpu_usage=$(top -bn1 | grep "Cpu(s)" | awk '{print 100 -$8}' | cut -d'.' -f1) log "当前 CPU 使用率: ${cpu_usage}% (阈值:${CPU_THRESHOLD}%)" if [[ "$cpu_usage" =~ ^[0-9]+$ ]] && [ "$cpu_usage" -gt "$CPU_THRESHOLD" ]; then local msg="警告: CPU使用率为 ${cpu_usage}%,超过阈值${CPU_THRESHOLD}%,请及时关注并处理!" send_email "$SUBJECT" "$msg" else log "状态: 正常" fi } check_memory() { echo "--- 内存 检查 ---" | tee -a "$LOG_FILE" # 计算内存使用率 local mem_usage=$(free | awk '/Mem:/ {printf "%d", ($3/$2)*100}') log "当前 内存 使用率: ${mem_usage}% (阈值:${MEM_THRESHOLD}%)" if [ "$mem_usage" -gt "$MEM_THRESHOLD" ]; then local msg="警告: 内存使用率为 ${mem_usage}%,超过阈值${MEM_THRESHOLD}%,请及时关注并处理!" send_email "$SUBJECT" "$msg" else log "状态: 正常" fi } check_disk() { echo "--- 磁盘 检查 ---" | tee -a "$LOG_FILE" local alert_triggered=0 # 使用进程替换 while read output; do local usep=$(echo "$output" | awk '{print $1}' | cut -d'%' -f1) local partition=$(echo "$output" | awk '{print $2}') if [[ "$usep" =~ ^[0-9]+$ ]]; then log "分区 $partition 使用率:${usep}%" if [ "$usep" -ge "$DISK_THRESHOLD" ]; then local msg="警告: 磁盘分区 $partition 使用率为${usep}%,超过阈值 ${DISK_THRESHOLD}%,请及时关注并处理!" send_email "$SUBJECT" "$msg" alert_triggered=1 fi fi done < <(df -h | grep -vE '^Filesystem|tmpfs|cdrom|overlay' | awk '{ print $5 " "$1 }') if [ "$alert_triggered" -eq 0 ]; then log "状态: 所有分区正常" fi } check_login_failures() { echo "--- 安全 检查 (登录失败) ---" | tee -a "$LOG_FILE" local fail_count=0 if [ -f /var/log/auth.log ]; then fail_count=$(grep "Failed password" /var/log/auth.log 2>/dev/null | tail -n 100 | wc -l) elif [ -f /var/log/secure ]; then fail_count=$(grep "Failed password" /var/log/secure 2>/dev/null | tail -n 100 | wc -l) fi log "最近100条日志中检测到登录失败次数: ${fail_count} (阈值:${LOGIN_FAIL_THRESHOLD})" if [ "$fail_count" -ge "$LOGIN_FAIL_THRESHOLD" ]; then local msg="安全警告: 检测到登录失败 ${fail_count} 次,超过阈值${LOGIN_FAIL_THRESHOLD} 次" send_email "$SUBJECT" "$msg" else log "状态: 安全" fi } # ---------------- 主程序 ---------------- main() { echo " " | tee -a "$LOG_FILE" echo "========================================" | tee -a "$LOG_FILE" log "MDM2.0 $(hostname) 操作系统健康巡检报告" log "检查时间:$(date '+%Y-%m-%d %H:%M:%S')" log "当前IP: $(hostname -I | awk '{print $1}')" echo "========================================" | tee -a "$LOG_FILE" check_cpu echo " " | tee -a "$LOG_FILE" check_memory echo " " | tee -a "$LOG_FILE" check_disk echo " " | tee -a "$LOG_FILE" check_login_failures echo " " | tee -a "$LOG_FILE" echo "========================================" | tee -a "$LOG_FILE" log "检查结束" echo "========================================" | tee -a "$LOG_FILE" } main设置定时任务,我这里是每5分钟
*/5 * * * * /data/script/monitor/system_monitor.sh查看执行结果
异常告警通知
其他:
该脚本的可塑性较高,灵活配置,根据实际需要进行改造即可。