前几天一个朋友跟我吐槽,说他的网站半夜挂掉了,第二天早上才被用户发现。原因是服务器磁盘被日志文件塞满,整个系统直接卡死。这让我想起自己刚接触服务器时也踩过类似的坑——服务器监控这件事,看似不起眼,关键时刻能救命。
市面上确实有不少成熟的监控方案,比如Zabbix、Prometheus、Grafana,功能强大、可视化做得也好。但对于个人站长或小型项目来说,这些工具往往显得有点"重"——部署麻烦、资源占用高、配置复杂。今天我就分享一个轻量级的服务器监控脚本,用Bash和Python各写一版,简单实用,开箱即用。
监控脚本到底该盯什么?
在写代码之前,先搞清楚核心需求。对于大多数Linux服务器来说,最需要盯紧的就三样东西:
- CPU负载:CPU打满说明系统超负荷运转,服务响应会变得极慢
- 内存使用:内存不足会触发OOM Killer,直接把进程杀掉,服务直接挂掉
- 磁盘空间:磁盘满了会导致数据库写入失败、日志无法写入,系统直接宕机
搞清楚监控目标,接下来看怎么实现。我准备了两个版本:Bash版适合纯Linux环境的轻量场景,Python版功能更全面,适合需要灵活扩展的场景。
Bash版:轻量到极致
Bash脚本的优势在于零依赖,任何Linux系统都能直接跑。下面这个脚本会每分钟记录一次CPU、内存、磁盘的使用率,写入日志文件,并在超过阈值时发送邮件告警。
#!/bin/bash
# ==============================================
# 服务器监控脚本 - Bash版
# 功能:监控CPU/内存/磁盘,超阈值时告警
# 用法:保存为monitor.sh,chmod +x monitor.sh
# 然后添加到crontab每分钟执行
# ==============================================
# ---------- 配置区 ----------
CPU_THRESHOLD=80 # CPU使用率阈值(%)
MEM_THRESHOLD=80 # 内存使用率阈值(%)
DISK_THRESHOLD=90 # 磁盘使用率阈值(%)
LOG_FILE="/var/log/server_monitor.log" # 日志文件
ALERT_EMAIL="admin@example.com" # 告警邮箱
# ---------- 获取系统状态 ----------
# CPU使用率:top命令取第二行Cpu(s)的us值
CPU_LOAD=$(top -bn1 | grep "Cpu(s)" | awk '{print $2}' | cut -d'%' -f1)
# 内存使用率:free命令计算used/total百分比
MEM_USED=$(free | awk '/Mem:/ {printf "%.0f", $3/$2 * 100}')
# 磁盘使用率:df命令取根分区第5列
DISK_USED=$(df / | awk 'NR==2 {print $5}' | tr -d '%')
# ---------- 写入日志 ----------
echo "$(date '+%Y-%m-%d %H:%M:%S') | CPU: ${CPU_LOAD}% | 内存: ${MEM_USED}% | 磁盘: ${DISK_USED}%" >> "$LOG_FILE"
# ---------- 阈值检查与告警 ----------
check_and_alert() {
local value=$1
local threshold=$2
local name=$3
# 数值比较,超过阈值则告警
if [ "$value" -gt "$threshold" ]; then
ALERT_MSG="服务器告警:${name}使用率 ${value}% 超过阈值 ${threshold}%"
echo "$(date '+%Y-%m-%d %H:%M:%S') | 告警:${name}使用率 ${value}%" >> "$LOG_FILE"
# 发送邮件告警(需要系统已配置mail命令)
echo "$ALERT_MSG" | mail -s "【告警】${name}使用率超阈值" "$ALERT_EMAIL"
fi
}
# 依次检查CPU、内存、磁盘
check_and_alert "$CPU_LOAD" "$CPU_THRESHOLD" "CPU"
check_and_alert "$MEM_USED" "$MEM_THRESHOLD" "内存"
check_and_alert "$DISK_USED" "$DISK_THRESHOLD" "磁盘"
这个脚本的逻辑很直观:先通过top、free、df三个Linux自带命令拿到系统指标,再逐个和阈值比较,超了就调用mail命令发邮件。注意,邮件发送需要系统预先配置好mail命令,比如安装mailutils或postfix。
Python版:更强大的控制力
如果你需要更灵活的监控逻辑,或者想对接企业微信、Slack等通知渠道,Python版会更顺手。它使用psutil库读取系统指标,代码更简洁,也更容易扩展。
#!/usr/bin/env python3-- coding: utf-8 --
"""
服务器监控脚本 - Python版
功能:监控CPU/内存/磁盘,超阈值时告警
依赖:pip install psutil
"""
import psutil
import logging
import smtplib
import time
from email.mime.text import MIMEText
from datetime import datetime
---------- 配置区 ----------
CPU_THRESHOLD = 80
MEM_THRESHOLD = 80
DISK_THRESHOLD = 90
LOG_FILE = "/var/log/server_monitor.log"
ALERT_EMAIL = "admin@example.com"
SMTP_SERVER = "smtp.example.com" # 你的SMTP服务器
SMTP_PORT = 587
SMTP_USER = "sender@example.com" # 发件邮箱
SMTP_PASSWORD = "your_password" # 邮箱密码或授权码
配置日志系统
logging.basicConfig(
filename=LOG_FILE,
level=logging.INFO,
format="%(asctime)s | %(levelname)s | %(message)s"
)
def get_cpu_usage():
"""获取CPU使用率(1秒采样)"""
return psutil.cpu_percent(interval=1)
def get_memory_usage():
"""获取内存使用率"""
return psutil.virtual_memory().percent
def get_disk_usage():
"""获取磁盘使用率(根分区)"""
return psutil.disk_usage('/').percent
def send_alert(subject, message):
"""通过SMTP发送告警邮件"""
msg = MIMEText(message, 'plain', 'utf-8')
msg['Subject'] = subject
msg['From'] = SMTP_USER
msg['To'] = ALERT_EMAIL
try:
server = smtplib.SMTP(SMTP_SERVER, SMTP_PORT)
server.starttls() # 启用TLS加密
server.login(SMTP_USER, SMTP_PASSWORD)
server.send_message(msg)
server.quit()
logging.info("告警邮件已发送")
except Exception as e:
logging.error(f"发送告警邮件失败: {e}")
def check_and_alert():
"""检查各项指标并触发告警"""
cpu = get_cpu_usage()
mem = get_memory_usage()
disk = get_disk_usage()
记录当前状态到日志
logging.info(f"CPU: {cpu}% | 内存: {mem}% | 磁盘: {disk}%")
print(f"[{datetime.now().strftime('%Y-%m-%d %H:%M:%S')}] CPU: {cpu}% | 内存: {mem}% | 磁盘: {disk}%")
逐项检查阈值
if cpu > CPU_THRESHOLD:
send_alert("【告警】CPU负载过高", f"当前CPU使用率: {cpu}%,阈值: {CPU_THRESHOLD}%")
if mem > MEM_THRESHOLD:
send_alert("【告警】内存使用过高", f"当前内存使用率: {mem}%,阈值: {MEM_THRESHOLD}%")
if disk > DISK_THRESHOLD:
send_alert("【告警】磁盘空间不足", f"当前磁盘使用率: {disk}%,阈值: {DISK_THRESHOLD}%")
if name == "__main__":
每分钟执行一次监控检查
print("服务器监控脚本已启动,每分钟检查一次...")
while True:
check_and_alert()
time.sleep(60) # 休眠60秒
Python版的核心逻辑和Bash版一样,但多了两个好处:一是psutil读取的指标更准确;二是可以很轻松地扩展为发送企业微信通知、Telegram消息,或者把监控数据推送到自己的API。
怎么部署?
Bash版部署很简单,保存脚本后加上执行权限,然后写入crontab即可:
# 编辑crontab
crontab -e添加一行,每分钟执行一次监控
/path/to/monitor.sh
Python版则需要先安装依赖,然后用nohup在后台运行:
# 安装psutil
pip install psutil后台运行Python监控脚本
nohup python3 /path/to/monitor.py &
如果你正在找一台靠谱的服务器来部署这个监控脚本,我个人比较推荐雨云服务器(优惠码:aabh),性价比不错,稳定性也过关,新用户还有优惠。
最后说点我的经验
写这个脚本的过程中,我踩过几个坑,在这里分享一下:
- 告警阈值别设太高也别设太低。CPU阈值设80%比较合理,太低会频繁误报,太高则可能等不到告警服务就挂了。
- 一定要写日志。告警邮件只是瞬时的,日志才是排查问题的一手资料。建议保留至少一个月的日志。
- 监控脚本本身也要监控。如果脚本挂了,比服务器更危险。可以再加一个crontab定时任务,检查监控脚本进程是否还在运行。
说到底,监控脚本是给服务器买的一份"保险"。它不能帮你避免所有问题,但能在问题发生时第一时间通知你。希望这个脚本能帮到正在为服务器操心的你。如果你有更好的想法,欢迎在评论区一起交流。
提示:以上脚本适用于大多数Linux发行版(Ubuntu、Debian、CentOS等)。生产环境使用前,建议先在测试服务器上跑一段时间,确认告警阈值和通知渠道都正常工作。
评论区: