python实现linux阈值检测与企微报警
阈值检测与企微报警
1、任务背景 生产环境中,单一的基础资源监控已无法满足高并发场景下的稳定性要求。为了精准定位系统瓶颈,需要构建一套覆盖资源饱和度(CPU/内存/磁盘)+ 系统压力(Load Average)+ 网络吞吐(Network I/O)”的全链路健康监测体系。通过设定多维度的安全水位阈值(如 Load > 5.0 或 CPU > 80%),在任一关键指标异常时通过企业微信实时报警,并自动归档故障现场数据
2、任务拆解
全栈指标采集:利用 psutil 库同步采集服务器的五大核心指标:CPU 使用率、内存占用、磁盘空间、系统平均负载(1分钟/5分钟)以及网络实时速率(上传/下载),形成完整的服务器健康画像。
复合阈值判定:当满足以下任一条件时判定为异常:
资源饱和:CPU > 80% 或 内存 > 90% 或 磁盘 > 85%;
系统阻塞:系统 1 分钟平均负载 > 预设阈值(如 5.0);
网络拥塞:网络流量出现持续异常高吞吐。
告警与日志审计:一旦检测到异常,立即触发企业微信 Webhook 接口推送包含具体故障指标的告警信息,同步将故障发生时的所有资源快照写入本地日志,为后续的根因分析(RCA)提供数据支撑。
企微接口文档:https://developer.work.weixin.qq.com/document/path/91770
3、代码实现
点击查看代码
# 导入相关模块
import psutil
import time
import requests
from datetime import datetime
LOG_FILE = 'resource_alert.log'
# 定义阈值 以及 企业告警链接地址
CPU_THRESHOLD = 80
MEMORY_THRESHOLD = 90
DISK_THRESHOLD = 85
# 系统负载阈值 (例如 4核CPU 建议设为 4.0 或 5.0)
LOAD_THRESHOLD = 5.0
#修改为你的企业微信接口
WEBHOOK_URL = 'https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key='
# 日志记录函数
def log_alert(resource_type, usage, threshold):
# 获取当前时间
current_time = datetime.now().strftime('%Y-%m-%d %H:%M:%S')
# 格式化日志信息
message = f'[{current_time}] {resource_type}使用率过高,超过了阈值{threshold},当前数值为{usage}\n'
# 打开文件并写入日志
with open(LOG_FILE, 'a', encoding='utf-8') as file:
file.write(message)
print(f"!!! 触发告警: {message.strip()}")
def send_wechat_alert(message):
# 定义header头信息
headers = {'Content-Type': 'application/json'}
# 定义传输数据
data = {
"msgtype": "text",
"text": {
"content": f"【服务器监控告警】\n{message}"
}
}
try:
response = requests.post(url=WEBHOOK_URL, headers=headers, json=data)
if response.status_code == 200:
print('告警发送成功!')
else:
print(f'告警发送失败,状态码: {response.status_code}')
except Exception as e:
print(f'企业微信接口调用失败,错误信息为:{e}')
def get_network_speed(interval=1):
"""
计算网络速率 (KB/s),同时利用这段等待时间获取CPU使用率
"""
# 1. 获取初始网络计数
net_before = psutil.net_io_counters()
# 2. 获取CPU使用率 (这里会阻塞 interval 秒)
cpu_usage = psutil.cpu_percent(interval=interval)
# 3. 获取结束网络计数
net_after = psutil.net_io_counters()
# 4. 计算速率 (字节 -> KB)
sent_speed = (net_after.bytes_sent - net_before.bytes_sent) / 1024 / interval
recv_speed = (net_after.bytes_recv - net_before.bytes_recv) / 1024 / interval
return cpu_usage, sent_speed, recv_speed
def check_resource_usage():
# 1. 获取 CPU 和 网络速率 (耗时1秒)
cpu_usage, sent_speed, recv_speed = get_network_speed(interval=1)
# 2. 获取内存使用率
memory_usage = psutil.virtual_memory().percent
# 3. 获取磁盘使用率
disk_usage = psutil.disk_usage('/').percent
# 4. 获取系统负载 (新增)
# getloadavg() 返回 (1分钟, 5分钟, 15分钟) 的负载元组
try:
load_avg = psutil.getloadavg()
load_1min = load_avg[0]
except AttributeError:
# Windows 系统可能不支持 getloadavg,做个兼容处理
load_1min = 0.0
# ================= 打印当前状态 (包含网络和Load) =================
print(f'资源监控 -> CPU:{cpu_usage}% | 内存:{memory_usage}% | 磁盘:{disk_usage}% | Load(1m):{load_1min:.2f}')
print(f'网络流量 -> 上传: {sent_speed:.2f} KB/s | 下载: {recv_speed:.2f} KB/s')
print('-' * 50)
# ================= 告警逻辑判断 =================
# CPU 判断
if cpu_usage > CPU_THRESHOLD:
log_alert('CPU', f"{cpu_usage}%", f"{CPU_THRESHOLD}%")
send_wechat_alert(f'CPU使用率过高!\n当前: {cpu_usage}%\n阈值: {CPU_THRESHOLD}%')
# 内存 判断
if memory_usage > MEMORY_THRESHOLD:
log_alert('内存', f"{memory_usage}%", f"{MEMORY_THRESHOLD}%")
send_wechat_alert(f'内存使用率过高!\n当前: {memory_usage}%\n阈值: {MEMORY_THRESHOLD}%')
# 磁盘 判断
if disk_usage > DISK_THRESHOLD:
log_alert('磁盘', f"{disk_usage}%", f"{DISK_THRESHOLD}%")
send_wechat_alert(f'磁盘使用率过高!\n当前: {disk_usage}%\n阈值: {DISK_THRESHOLD}%')
# 系统负载 判断
if load_1min > LOAD_THRESHOLD:
log_alert('系统负载(Load 1min)', load_1min, LOAD_THRESHOLD)
send_wechat_alert(f'系统负载过高!\n当前1分钟负载: {load_1min}\n阈值: {LOAD_THRESHOLD}')
if __name__ == '__main__':
try:
print('开始全维度监控系统资源 (CPU/内存/磁盘/负载/网络)...(按Ctrl+C停止)')
while True:
check_resource_usage()
# 这里的sleep可以适当缩短,因为 get_network_speed 已经阻塞了1秒
time.sleep(4)
except KeyboardInterrupt:
print('\n监控已手动停止!')

浙公网安备 33010602011771号