系统监控脚本#
脚本说明#
系统监控脚本用于实时监控系统资源使用情况,包括CPU、内存、磁盘、网络等,并在超过阈值时发送告警。
脚本代码#
#!/bin/bash
# 系统监控脚本
# 功能:监控系统资源使用情况并告警
# 作者:System Admin
# 日期:2026-01-01
set -euo pipefail
# 配置变量
LOG_FILE="/var/log/system_monitor.log"
ALERT_LOG="/var/log/system_alert.log"
EMAIL_RECIPIENT="admin@example.com"
CPU_THRESHOLD=80
MEMORY_THRESHOLD=80
DISK_THRESHOLD=90
NETWORK_THRESHOLD=1000000 # 网络流量阈值(字节/秒)
INTERVAL=60 # 监控间隔(秒)
# 颜色定义
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[0;33m'
BLUE='\033[0;34m'
NC='\033[0m'
# 日志函数
log() {
local level=$1
shift
local timestamp=$(date '+%Y-%m-%d %H:%M:%S')
echo "[$timestamp] [$level] $@" | tee -a "$LOG_FILE"
}
log_info() {
log "INFO" "$@"
}
log_error() {
log "ERROR" "$@"
}
log_warning() {
log "WARNING" "$@"
}
# 告警函数
send_alert() {
local message=$1
local timestamp=$(date '+%Y-%m-%d %H:%M:%S')
# 记录告警日志
echo "[$timestamp] ALERT: $message" >> "$ALERT_LOG"
# 发送邮件告警
if [ -n "$EMAIL_RECIPIENT" ]; then
echo "$message" | mail -s "系统告警" "$EMAIL_RECIPIENT"
fi
# 控制台输出
echo -e "${RED}[ALERT]${NC} $message"
}
# 监控CPU使用率
monitor_cpu() {
local cpu_usage=$(top -bn1 | grep "Cpu(s)" | awk '{print $2}' | cut -d'%' -f1)
local cpu_usage_int=${cpu_usage%.*}
log_info "CPU使用率: ${cpu_usage}%"
if [ $cpu_usage_int -ge $CPU_THRESHOLD ]; then
send_alert "CPU使用率过高: ${cpu_usage}%"
return 1
fi
return 0
}
# 监控内存使用率
monitor_memory() {
local total=$(free -m | grep Mem | awk '{print $2}')
local used=$(free -m | grep Mem | awk '{print $3}')
local usage=$((used * 100 / total))
log_info "内存使用率: ${usage}% (已用: ${used}MB / 总计: ${total}MB)"
if [ $usage -ge $MEMORY_THRESHOLD ]; then
send_alert "内存使用率过高: ${usage}%"
return 1
fi
return 0
}
# 监控磁盘使用率
monitor_disk() {
local alert=0
while read -r line; do
local mount_point=$(echo "$line" | awk '{print $6}')
local usage=$(echo "$line" | awk '{print $5}' | cut -d'%' -f1)
log_info "磁盘使用率 [$mount_point]: ${usage}%"
if [ $usage -ge $DISK_THRESHOLD ]; then
send_alert "磁盘使用率过高 [$mount_point]: ${usage}%"
alert=1
fi
done < <(df -h | grep -E '^/dev/')
return $alert
}
# 监控网络流量
monitor_network() {
local interface=$(ip route | grep default | awk '{print $5}' | head -n 1)
if [ -z "$interface" ]; then
log_warning "无法获取网络接口"
return 0
fi
# 获取初始流量
local rx_bytes1=$(cat /sys/class/net/$interface/statistics/rx_bytes)
local tx_bytes1=$(cat /sys/class/net/$interface/statistics/tx_bytes)
sleep 1
# 获取1秒后的流量
local rx_bytes2=$(cat /sys/class/net/$interface/statistics/rx_bytes)
local tx_bytes2=$(cat /sys/class/net/$interface/statistics/tx_bytes)
# 计算流量(字节/秒)
local rx_rate=$((rx_bytes2 - rx_bytes1))
local tx_rate=$((tx_bytes2 - tx_bytes1))
local total_rate=$((rx_rate + tx_rate))
log_info "网络流量 [$interface]: 接收: ${rx_rate}B/s, 发送: ${tx_rate}B/s"
if [ $total_rate -ge $NETWORK_THRESHOLD ]; then
send_alert "网络流量过高: ${total_rate}B/s"
return 1
fi
return 0
}
# 监控进程
monitor_processes() {
local process_count=$(ps aux | wc -l)
log_info "进程数量: $process_count"
# 检查僵尸进程
local zombie_count=$(ps aux | grep -c "Z")
if [ $zombie_count -gt 0 ]; then
send_alert "发现僵尸进程: $zombie_count 个"
return 1
fi
return 0
}
# 监控系统负载
monitor_load() {
local load=$(uptime | awk -F'load average:' '{print $2}' | awk '{print $1}' | cut -d',' -f1)
local cpu_count=$(nproc)
local load_threshold=$((cpu_count * 2))
log_info "系统负载: $load (CPU核心数: $cpu_count)"
if (( $(echo "$load > $load_threshold" | bc -l) )); then
send_alert "系统负载过高: $load"
return 1
fi
return 0
}
# 监控服务状态
monitor_services() {
local services=("nginx" "mysql" "ssh" "cron")
local alert=0
for service in "${services[@]}"; do
if systemctl is-active --quiet "$service"; then
log_info "服务状态 [$service]: 运行中"
else
send_alert "服务未运行: $service"
alert=1
fi
done
return $alert
}
# 生成监控报告
generate_report() {
local date=$(date +%Y-%m-%d)
local report_file="/tmp/system_report_$date.txt"
{
echo "系统监控报告"
echo "生成时间: $(date)"
echo ""
echo "===== CPU信息 ====="
lscpu | grep -E "Model name|CPU\(s\)|Thread"
echo ""
echo "===== 内存信息 ====="
free -h
echo ""
echo "===== 磁盘信息 ====="
df -h
echo ""
echo "===== 网络信息 ====="
ip addr
echo ""
echo "===== 系统负载 ====="
uptime
echo ""
echo "===== 进程信息 ====="
ps aux --sort=-%cpu | head -10
echo ""
echo "===== 服务状态 ====="
systemctl list-units --type=service --state=running
} > "$report_file"
log_info "监控报告已生成: $report_file"
}
# 主监控循环
main() {
log_info "===== 开始系统监控 ====="
log_info "监控间隔: ${INTERVAL}秒"
# 生成初始报告
generate_report
# 监控循环
while true; do
log_info "===== 执行监控检查 ====="
local alerts=0
# 执行各项监控
monitor_cpu || alerts=$((alerts + 1))
monitor_memory || alerts=$((alerts + 1))
monitor_disk || alerts=$((alerts + 1))
monitor_network || alerts=$((alerts + 1))
monitor_processes || alerts=$((alerts + 1))
monitor_load || alerts=$((alerts + 1))
monitor_services || alerts=$((alerts + 1))
# 汇总结果
if [ $alerts -eq 0 ]; then
log_info "所有监控项正常"
else
log_warning "发现 $alerts 个告警"
fi
# 等待下一次监控
sleep $INTERVAL
done
}
# 信号处理
trap 'log_info "接收到退出信号,停止监控"; exit 0' SIGINT SIGTERM
# 执行主函数
main "$@"使用说明#
修改配置变量:
LOG_FILE: 日志文件路径ALERT_LOG: 告警日志路径EMAIL_RECIPIENT: 告警邮件接收者CPU_THRESHOLD: CPU使用率阈值(%)MEMORY_THRESHOLD: 内存使用率阈值(%)DISK_THRESHOLD: 磁盘使用率阈值(%)NETWORK_THRESHOLD: 网络流量阈值(字节/秒)INTERVAL: 监控间隔(秒)
添加执行权限:
chmod +x system_monitor.sh执行脚本:
./system_monitor.sh后台运行:
nohup ./system_monitor.sh > /dev/null 2>&1 &设置为系统服务:
sudo cp system_monitor.sh /usr/local/bin/ sudo chmod +x /usr/local/bin/system_monitor.sh # 创建systemd服务文件 sudo tee /etc/systemd/system/system-monitor.service > /dev/null <<EOF [Unit] Description=System Monitor Service After=network.target [Service] Type=simple ExecStart=/usr/local/bin/system_monitor.sh Restart=always RestartSec=10 [Install] WantedBy=multi-user.target EOF sudo systemctl daemon-reload sudo systemctl enable system-monitor sudo systemctl start system-monitor
功能特点#
- 实时监控CPU、内存、磁盘、网络等资源
- 可配置的告警阈值
- 多种告警方式(日志、邮件)
- 详细的监控日志
- 系统报告生成
- 服务状态监控
- 进程监控
- 系统负载监控
依赖项#
- bc: 用于浮点数计算
- mail: 用于发送邮件告警
- systemd: 用于服务管理(可选)
注意事项#
- 根据实际情况调整监控阈值
- 确保邮件服务配置正确
- 定期检查告警日志
- 监控脚本会持续运行,注意资源消耗
- 建议在测试环境验证后再部署到生产环境