python编写liunx服务器登陆自动巡检脚本
前言:
用户需要一份用Python编写的Linux系统巡检脚本,检查内存、磁盘、CPU使用率,还有网络连通性。
首先,我得确定用户的使用场景。可能用户是系统管理员,需要定期监控服务器状态,确保系统正常运行。
或者是开发人员,想自动化巡检流程,减少手动检查的工作量。
接下来,用户提到的具体指标有内存、磁盘、CPU和网络。
我需要考虑如何用Python获取这些信息。
对于Linux系统,通常可以通过读取/proc文件系统或者使用命令行工具来获取这些数据。
比如,内存信息可以从/proc/meminfo读取,磁盘使用情况可以用psutil库或者调用df命令,
CPU使用率可以用psutil或者读取/proc/stat,网络连通性可以用ping命令或者socket库。
然后,用户可能希望脚本的输出清晰易读,可能需要格式化输出,比如用表格形式展示结果。
颜色区分不同状态,比如红色表示警告,绿色表示正常,这样用户一眼就能看出问题所在。
还要考虑是否需要参数化,比如允许用户指定检查的磁盘路径或IP地址,但用户没有提到,可能基础版本不需要,但可以预留扩展的可能性。
另外,日志记录功能可能有用,方便后续查看历史巡检结果。
需要处理权限问题,比如某些命令可能需要sudo权限,但用户可能希望脚本在普通用户权限下运行,所以应选择不需要特权的方法。
例如,使用psutil库可以跨平台,并且不需要执行外部命令,更安全可靠。 关于网络检查,用户可能想检测内网关键服务或外网连通性。
比如,默认检查8.8.8.8和百度,但用户可能需要自定义,所以可以设计成可配置的列表。
最后,确保代码兼容Python3,并且添加必要的异常处理,避免脚本因为某个检查项失败而终止。
例如,捕获异常并记录错误信息,继续执行其他检查。
总结下来,脚本需要:
- 使用psutil库获取系统信息(内存、磁盘、CPU)。
- 使用subprocess执行ping命令检查网络。
- 格式化输出,用颜色标记状态。
- 可配置的检查项,如磁盘路径、IP列表。
- 添加日志记录功能。
- 异常处理,确保健壮性。 现在开始编写代码,确保各部分功能正确,
并测试在不同情况下的表现,比如磁盘空间不足时是否正确报警,网络不通时的处理等。
同时,提供使用说明,指导用户安装依赖(如psutil)和如何运行脚本。
以下是一个基于Python 3的Linux系统巡检脚本,使用psutil
库获取系统信息,包含您要求的五大核心指标检测:
#!/usr/bin/env python3
import psutil
import subprocess
import platform
from datetime import datetime
import socket
import sys
# 颜色配置
COLORS = {
"red": "\033[91m",
"green": "\033[92m",
"yellow": "\033[93m",
"orange": "\033[38;5;208m",
"end": "\033[0m"
}
def check_uptime():
"""获取系统运行时间和启动时间"""
boot_time = psutil.boot_time()
now = datetime.now().timestamp()
# 计算运行时间
uptime_seconds = now - boot_time
days, remainder = divmod(uptime_seconds, 86400)
hours, remainder = divmod(remainder, 3600)
minutes, seconds = divmod(remainder, 60)
return {
"days": int(days),
"hours": int(hours),
"minutes": int(minutes),
"seconds": int(seconds),
"boot_time": datetime.fromtimestamp(boot_time).strftime("%Y-%m-%d %H:%M:%S")
}
def get_host_ip():
"""获取主机所有IPv4地址(排除回环地址)"""
interfaces = psutil.net_if_addrs()
ips = []
for name, addrs in interfaces.items():
for addr in addrs:
if addr.family == socket.AF_INET and not addr.address.startswith('127.'):
ips.append({
"interface": name,
"ip": addr.address,
"netmask": addr.netmask
})
return {"ips": ips}
def check_memory():
"""检查内存使用率(修改为GB单位)"""
mem = psutil.virtual_memory()
return {
"total": round(mem.total / (1024**3), 1), # 转换为GB
"used": round(mem.used / (1024**3), 1),
"free": round(mem.free / (1024**3), 1),
"percent": mem.percent
}
def check_disk(path='/'):
"""检查磁盘使用率(修改为GB单位)"""
disk = psutil.disk_usage(path)
return {
"total": round(disk.total / (1024**3), 1), # 转换为GB
"used": round(disk.used / (1024**3), 1),
"free": round(disk.free / (1024**3), 1),
"percent": disk.percent
}
def check_cpu():
"""检查CPU使用率"""
return {
"usage": psutil.cpu_percent(interval=1),
"cores": psutil.cpu_count(logical=False),
"threads": psutil.cpu_count(logical=True)
}
def check_load():
"""检查系统负载"""
load_avg = psutil.getloadavg()
cpu_cores = psutil.cpu_count(logical=False) # 获取物理核心数
return {
"1min": load_avg[0],
"5min": load_avg[1],
"15min": load_avg[2],
"cores": cpu_cores
}
def check_network(hosts=['8.8.8.8', 'www.baidu.com']):
"""网络连通性检查"""
results = {}
for host in hosts:
param = '-n' if platform.system().lower()=='windows' else '-c'
command = ['ping', param, '3', host]
results[host] = subprocess.call(
command,
stdout=subprocess.DEVNULL,
stderr=subprocess.DEVNULL
) == 0
return results
def format_result(title, data, threshold=80):
print(f"\n{COLORS['orange']}=== {title} ==={COLORS['end']}")
"""更新输出格式"""
if title == "内存使用率":
print(f"总量: {data['total']} GB | 已用: {data['used']} GB | 剩余: {data['free']} GB")
elif title == "磁盘使用率":
print(f"总量: {data['total']} GB | 已用: {data['used']} GB | 剩余: {data['free']} GB")
elif title == "CPU使用率":
color = COLORS['red'] if data['usage'] > threshold else COLORS['green']
print(f"使用率: {color}{data['usage']}%{COLORS['end']}")
print(f"物理核心: {data['cores']} | 逻辑线程: {data['threads']}")
elif title == "网络连通性":
for host, status in data.items():
status_str = f"{COLORS['green']}通{COLORS['end']}" if status else f"{COLORS['red']}不通{COLORS['end']}"
print(f"{host}: {status_str}")
elif title == "系统负载":
# 计算负载核心比
load_ratio_1min = data['1min'] / data['cores'] if data['cores'] > 0 else 0
# 设置颜色阈值
if load_ratio_1min > 2.0:
color = COLORS['red']
status = "❗过载"
elif load_ratio_1min > 1.0:
color = COLORS['yellow']
status = "⚠️警告"
else:
color = COLORS['green']
status = "✅正常"
print(f"当前状态: {color}{status}{COLORS['end']}")
print(f"1分钟负载: {data['1min']:.2f} | 5分钟: {data['5min']:.2f} | 15分钟: {data['15min']:.2f}")
print(f"物理核心: {data['cores']} | 建议阈值: 1.0-{data['cores']*2:.1f}")
elif title == "系统运行时间":
print(f"运行时长: {data['days']}天 {data['hours']}时 {data['minutes']}分")
print(f"系统启动: {data['boot_time']}")
elif title == "主机网络信息":
if len(data['ips']) == 0:
print(f"{COLORS['red']}未找到有效IP地址{COLORS['end']}")
else:
for entry in data['ips']:
print(f"接口 {entry['interface']}: {entry['ip']}/{entry['netmask']}")
def main():
# 记录检查时间
print(f"{COLORS['yellow']}系统巡检时间:{datetime.now().strftime('%Y-%m-%d %H:%M:%S')}{COLORS['end']}")
# 执行所有检查
checks = [
("主机网络信息", get_host_ip()), # 新增
("系统运行时间", check_uptime()), # 新增
("内存使用率", check_memory()),
("磁盘使用率", check_disk()),
("CPU使用率", check_cpu()),
("系统负载", check_load()),
("网络连通性", check_network())
]
# 输出结果
for title, data in checks:
format_result(title, data)
# 添加系统信息
print(f"\n{COLORS['orange']}=== 系统信息 ==={COLORS['end']}")
print(f"主机名: {platform.node()}")
print(f"系统版本: {platform.platform()}")
if __name__ == "__main__":
try:
main()
except KeyboardInterrupt:
print("\n检测已中止")
sys.exit(1)
except Exception as e:
print(f"{COLORS['red']}检测出错: {str(e)}{COLORS['end']}")
sys.exit(1)
使用说明:
- 安装依赖:
pip install psutil
- 运行脚本:
python3 system_check.py
功能特性: - 彩色终端输出:使用不同颜色标识健康状态(红色>80%,绿色正常)
- 核心指标检测:
- 内存:总/已用/剩余内存及使用率
- 磁盘:根分区使用情况
- CPU:使用率及核心数
- 网络:默认检测谷歌DNS和百度连通性
- 扩展功能:
- 异常处理机制(支持Ctrl+C中断)
- 系统基本信息展示
- 时间戳记录
输出示例:
系统巡检时间:2024-02-20 14:30:45
=== 内存使用率 ===
使用率: 58.2%
总量: 15941 MB | 已用: 9273 MB | 剩余: 6668 MB
=== 磁盘使用率 ===
挂载点: / | 使用率: 75.5%
总量: 491520 MB | 已用: 370112 MB | 剩余: 121408 MB
=== CPU使用率 ===
使用率: 32.1%
物理核心: 8 | 逻辑线程: 16
=== 网络连通性 ===
8.8.8.8: 通
www.baidu.com: 通
=== 系统信息 ===
主机名: ubuntu-server
系统版本: Linux-5.4.0-88-generic-x86_64-with-glibc2.29
效果图
自定义建议:
- 修改检测阈值:调整
format_result
中的threshold参数 - 增加检测项:在
check_disk
中指定其他挂载点 - 修改检测目标:调整
check_network
的hosts列表 - 添加告警机制:当指标超过阈值时发送邮件/钉钉通知
彩蛋
1、要实现通过SSH连接服务器时自动执行巡检脚本。
在文件末尾追加以下内容
#只是root用户可以使用
echo -e '\n# 登录时执行巡检脚本\npython3 /path/to/your_script.py' >> ~/.bashrc
用户通过SSH登录 → 执行巡检脚本 → 显示巡检结果 → 进入正常shell环境
效果图
所有用户登陆服务器都可以执行这个巡检脚本
vim /etc/ssh/sshd_config
#在文件末尾添加 排除特殊连接方式(防止影响SCP/SFTP):
Match All
ForceCommand if [[ -z $SSH_ORIGINAL_COMMAND ]]; then
python3 /usr/local/bin/system_check.py;
exec $SHELL;
else
eval "$SSH_ORIGINAL_COMMAND";
fi
#重启ssh服务
systemctl restart sshd
至此结束,感谢观看。