专栏简介: 本专栏将从单机巡检起步,逐步演进到多机批量巡检、异常告警推送、可视化Dashboard,最终构建一套完整的企业级自动化运维平台。每一篇都是生产环境实战沉淀,拒绝拒绝Hello World式教学。

📌 本篇导读

作为专栏的第一篇,我们将聚焦于单机巡检V1版本的实现。通过本篇的学习,你将掌握:

  1. 如何使用 psutil 库采集服务器的 CPU、内存、磁盘等核心指标。
  2. 如何设计高内聚、低耦合的模块化项目结构。
  3. 如何实现基于阈值的异常检测逻辑。
  4. 如何自动生成格式化的 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 版本。我们实现了:

  1. 模块化开发:建立了 collectorsanalyzerreport 三层架构,代码结构清晰。
  2. 指标采集:熟练运用 psutil 获取 CPU、内存、磁盘的核心运行数据。
  3. 阈值告警:实现了基础的异常判断逻辑,能够自动发现潜在风险。
  4. 报告输出:将巡检结果自动化输出为 HTML 文件。

⚠️ V1 版本的局限性

虽然 V1 版本已经跑通了核心流程,但距离真正的“企业级”还有一段距离:

只能巡检本机:生产环境有几十台服务器,不可能每台都去部署这套代码。

🚀 下篇预告:多机巡检与配置化

在下一篇文章中,我们将对系统进行大升级,迈入 V2 版本

  1. 引入 Paramiko:实现 SSH 远程免密登录,在一台控制机上采集所有目标服务器的数据。
  2. YAML 配置驱动:将服务器 IP 列表、账号密码、告警阈值全部剥离到 server.yaml 中。

🌟 创作不易,如果这篇文章对你有帮助,欢迎点赞 👍、收藏 ⭐、关注 🔔 三连支持!你的支持是我持续更新的最大动力。有任何问题或建议,欢迎在评论区留言交流,我会一一回复!

Logo

Agent 垂直技术社区,欢迎活跃、内容共建。

更多推荐