企业级Python自动化运维实战(一):从零构建服务器单机巡检系统
专栏简介: 本专栏将从单机巡检起步,逐步演进到多机批量巡检、异常告警推送、可视化Dashboard,最终构建一套完整的企业级自动化运维平台。每一篇都是生产环境实战沉淀,拒绝拒绝Hello World式教学。
📌 本篇导读
作为专栏的第一篇,我们将聚焦于单机巡检V1版本的实现。通过本篇的学习,你将掌握:
- 如何使用
psutil库采集服务器的 CPU、内存、磁盘等核心指标。 - 如何设计高内聚、低耦合的模块化项目结构。
- 如何实现基于阈值的异常检测逻辑。
- 如何自动生成格式化的 HTML 巡检报告。
一、 项目架构设计
在编写代码之前,良好的项目结构是企业级开发的基础。我们采用模块化设计,将数据采集、异常分析、报告生成等功能解耦,方便后续的维护和扩展。
#
#
#作者:饭要加加加
如需获取项目代码压缩包请关注同名公众号:饭要加加加 私信获取
#
#
server-inspection/
│
├── main.py # 程序入口(调度中心)
│
├── config/
│ └── server.yaml # 服务器配置(预留)
│
├── collectors/ # 指标采集层
│ ├── cpu.py # CPU采集
│ ├── memory.py # 内存采集
│ └── disk.py # 磁盘采集
│
├── ssh/
│ └── client.py # SSH连接模块(后续多机巡检使用)
│
├── analyzer/
│ └── check.py # 异常判断逻辑
│
├── report/
│ └── template.html # 报告模板(预留)
│
├── notify/
│ └── wechat.py # 消息通知(预留)
│
└── logs/
└── inspection.log # 运行日志
💡 设计思考:为什么一开始就要把目录分得这么细?
在实际企业项目中,“高内聚、低耦合” 是核心原则。把采集、分析、通知分开,意味着未来如果我们需要把“企业微信通知”换成“钉钉通知”,或者把“本地采集”换成“SSH远程采集”,只需要修改对应模块的代码,而不会影响主流程main.py的逻辑。
二、环境准备与项目初始化
1. 创建项目与虚拟环境
为了保证环境的纯净,避免不同项目之间的依赖冲突,我们强烈建议使用 Python 虚拟环境。
# 创建项目根目录并进入
mkdir server-inspection
cd server-inspection
# 安装Python(如果系统尚未安装)
yum -y install python
# 创建并激活虚拟环境
python3 -m venv venv
source venv/bin/activate
📌 Tip:激活虚拟环境后,你的命令行提示符前面会出现
(venv)字样,此时使用pip安装的包都会保存在该虚拟环境内,不会污染系统的全局 Python 环境。
2. 安装第三方依赖
我们在项目根目录创建 requirements.txt 文件并添加以下内容:
psutil
pyyaml
jinja2
requests
paramiko
执行安装:
pip install -r requirements.txt
pip list # 验证安装结果
依赖库说明:
psutil:跨平台的系统和进程监控库,是我们采集指标的核心。pyyaml:用于解析 YAML 配置文件。jinja2:强大的模板引擎,后续用于生成精美的 HTML 报告。requests:用于发送 HTTP 请求(如调用微信告警 API)。paramiko:用于实现 SSH 远程连接(第二篇多机巡检的核心)。
3. 初始化项目目录结构
# 创建各个功能模块目录
mkdir config collectors analyzer report notify logs
# 创建主入口文件
touch main.py
# 创建配置文件
touch config/server.yaml
# 创建采集模块文件
touch collectors/cpu.py
touch collectors/memory.py
touch collectors/disk.py
# 创建分析模块文件
touch analyzer/check.py
# 创建报告模块文件
touch report/report.py
# 创建通知模块文件
touch notify/wechat.py
💡 为什么要加
__init__.py? 它是Python包的标识文件,有了它才能使用from collectors.cpu import ...这样的跨模块导入。
三、 实现指标采集模块 (Collectors)
数据采集是巡检系统的第一步。我们将使用 psutil 库来获取系统的底层运行状态。
3.1 CPU 采集
编写 collectors/cpu.py:
import psutil
def get_cpu_usage():
cpu = psutil.cpu_percent(interval=5)
return cpu
if __name__ == "__main__":
print(get_cpu_usage())
🔍 代码解析:
psutil.cpu_percent(interval=5)中的interval=5非常关键。它表示阻塞 5 秒钟来计算这段时间内的 CPU 平均使用率。如果不设置interval,返回的将是自上一次调用以来的瞬时值,往往不够准确。
3.2 内存采集
编写 collectors/memory.py:
import psutil
def get_memory_usage():
memory = psutil.virtual_memory()
return {
"total": round(memory.total/1024/1024/1024,2),
"used": round(memory.used/1024/1024/1024,2),
"percent": memory.percent
}
if __name__=="__main__":
print(get_memory_usage())
🔍 代码解析:
psutil.virtual_memory()返回的是一个包含丰富内存信息的命名元组。这里我们通过除以1024**3将字节(Bytes)转换为更易读的 GB 单位,并使用round(..., 2)保留两位小数。最终返回一个字典,方便后续统一处理。
3.3 磁盘采集
编写 collectors/disk.py:
import psutil
def get_disk_usage():
disk = psutil.disk_usage("/")
return {
"total":
round(disk.total/1024/1024/1024,2),
"used":
round(disk.used/1024/1024/1024,2),
"percent":
disk.percent
}
if __name__=="__main__":
print(get_disk_usage())
🔍 代码解析:
psutil.disk_usage("/")用于获取根目录/所在磁盘分区的使用情况。在 Linux 系统中,根目录通常是系统盘。后续在 V2 版本中,我们可以将其优化为遍历所有挂载点,以监控数据盘。
3.4 整合采集数据
现在我们已经有了三个独立的采集模块,接下来在 main.py 中将它们串联起来,把采集到的数据统一存入一个字典中。
修改 main.py:
from collectors.cpu import get_cpu_usage
from collectors.memory import get_memory_usage
from collectors.disk import get_disk_usage
def main():
data={}
data["cpu"] = get_cpu_usage()
data["memory"] = get_memory_usage()
data["disk"] = get_disk_usage()
print(data)
if __name__=="__main__":
main()
💡 设计亮点:
将所有的指标数据收敛到一个data字典中,是一种非常好的做法。这样无论后续增加多少个采集项(如网络IO、进程数等),我们只需要往data字典里追加键值对即可,下游的分析模块和报告模块只需要接收这一个data参数。
四、 异常检测与逻辑串联 (Analyzer)
4.1 增加异常检测
编写 analyzer/check.py:
def check(data):
alarms=[]
if data["cpu"]>80:
alarms.append(
"CPU使用率过高"
)
if data["memory"]["percent"]>85:
alarms.append(
"内存使用率过高"
)
if data["disk"]["percent"]>90:
alarms.append(
"磁盘空间不足"
)
return alarms
🔍 代码解析:
这里我们写了三个基础阈值:CPU > 80%、内存 > 85%、磁盘 > 90%。当触发阈值时,将告警信息追加到alarms列表中。如果列表为空,则说明服务器状态健康。
4.2 整合主流程 main.py
将异常检测模块接入主流程,看看我们的巡检系统是否能正确发现问题。运行 python main.py,你将看到控制台打印出采集到的数据字典,以及检测出的异常列表。至此,我们的巡检系统已经具备了 “感知” 和 “思考” 的能力!
更新 main.py:
from collectors.cpu import get_cpu_usage
from collectors.memory import get_memory_usage
from collectors.disk import get_disk_usage
from analyzer.check import check #引入check模块下check函数
def main():
data={}
data["cpu"] = get_cpu_usage()
data["memory"] = get_memory_usage()
data["disk"] = get_disk_usage()
print(data)
alarm=check(data) #执行check函数
print("异常:")
print(alarm)
if __name__=="__main__":
main()
五、 生成巡检报告 (Report)
作为企业级运维工具,仅仅在控制台打印结果是不够的。我们需要将巡检结果持久化,生成一份直观、易读的报告文件,方便存档或发送给团队查阅。
5.1 编写报告生成逻辑
编写 report/report.py。这里我们使用 Python 的 f-string 格式化字符串,生成简单的报告
from datetime import datetime
def create_report(data, alarms):
content=f"""
服务器巡检报告
时间:
{datetime.now()}
CPU:
{data['cpu']}%
内存:
{data['memory']}
磁盘:
{data['disk']}
异常:
{alarms}
"""
with open("report.html","w") as f:
f.write(content)
我们选择HTML 具有极强的扩展性。虽然当前 V1 版本只是简单的文本拼接,但在后续版本中,我们可以引入 CSS 样式让报告变得非常精美,甚至可以使用
jinja2模板引擎渲染复杂的表格和图表
5.2 最终版 main.py 脚本
最后,我们将报告生成模块接入主流程,完成整个单机巡检 V1 版本的闭环。
最终版 main.py:
from collectors.cpu import get_cpu_usage
from collectors.memory import get_memory_usage
from collectors.disk import get_disk_usage
from analyzer.check import check
from report.report import create_report #引入report模块下create_report函数
def main():
data={}
data["cpu"] = get_cpu_usage()
data["memory"] = get_memory_usage()
data["disk"] = get_disk_usage()
print(data)
alarm=check(data)
print("异常:")
print(alarm)
create_report(data,alarm) #执行函数生成巡检文件
if __name__=="__main__":
main()
执行 python main.py 后,项目根目录下会生成一个 report.html 文件。目前不具备web页面访问,因为没有添加html相关标签格式,后续项目升级会逐步实现。
5.3添加定时任务
在巡检服务器上添加定时任务,比如设置每天早上九点巡检
crontab -e
0 9 * * * cd /root/server-inspection && python main.py
六、 本篇总结与下篇预告
✅ 本篇收获
在本文中,我们成功从零搭建了一个单机服务器巡检系统 V1 版本。我们实现了:
- 模块化开发:建立了
collectors、analyzer、report三层架构,代码结构清晰。 - 指标采集:熟练运用
psutil获取 CPU、内存、磁盘的核心运行数据。 - 阈值告警:实现了基础的异常判断逻辑,能够自动发现潜在风险。
- 报告输出:将巡检结果自动化输出为 HTML 文件。
⚠️ V1 版本的局限性
虽然 V1 版本已经跑通了核心流程,但距离真正的“企业级”还有一段距离:
只能巡检本机:生产环境有几十台服务器,不可能每台都去部署这套代码。
🚀 下篇预告:多机巡检与配置化
在下一篇文章中,我们将对系统进行大升级,迈入 V2 版本:
- 引入 Paramiko:实现 SSH 远程免密登录,在一台控制机上采集所有目标服务器的数据。
- YAML 配置驱动:将服务器 IP 列表、账号密码、告警阈值全部剥离到
server.yaml中。
🌟 创作不易,如果这篇文章对你有帮助,欢迎点赞 👍、收藏 ⭐、关注 🔔 三连支持!你的支持是我持续更新的最大动力。有任何问题或建议,欢迎在评论区留言交流,我会一一回复!
更多推荐


所有评论(0)