iT邦幫忙

2026 iThome 鐵人賽

DAY 8
0
AI 自動化

30 天打造 AI 自動化維運平台:從監控、告警到故障分析系列 第 8

Day 8|收到告警之後呢?用 Python 自動收集故障資訊

  • 分享至 

  • xImage
  •  

目前整個流程是:

server01

Prometheus

Grafana

Alert Rule

Discord

當 CPU 持續超過設定的門檻時,我們已經可以收到:

[FIRING]

Server01 High CPU

但收到通知之後,真正的維運工作才剛開始。

因為接下來通常還是要登入 Server,確認:

CPU 現在多少?
Memory 有沒有一起升高?
Disk 是否正常?
哪個 Process 正在吃 CPU?

所以今天想先解決這件事情。

既然這些資訊每次都要查,那能不能讓 Python 先幫我收集?

今天要做到什麼?

先不接 AI,也先不修改 Grafana。

今天只完成這個流程:

server01

Python

收集系統資訊

CPU
Memory
Disk
Process

輸出故障資訊

等這支程式可以正常工作之後,後面再想辦法讓 Grafana 告警自動觸發它。

Step 1:準備 Python 環境

先登入 server01:

ssh username@192.168.1.101

確認 Python:

python3 --version

接著準備虛擬環境:

sudo apt update
sudo apt install python3-venv -y

建立專案:

mkdir ~/aiops
cd ~/aiops

建立 Python Virtual Environment:

python3 -m venv venv

啟用:

source venv/bin/activate

接著安裝今天會使用的套件:

pip install psutil

psutil 可以讓 Python 取得系統的 CPU、Memory、Disk 和 Process 資訊。

Step 2:先取得基本主機資訊

建立:

nano collect_info.py

先從最基本的資訊開始:

import socket
import psutil
from datetime import datetime

hostname = socket.gethostname()

cpu = psutil.cpu_percent(interval=1)
memory = psutil.virtual_memory()
disk = psutil.disk_usage("/")

print("=== System Information ===")
print(f"Time: {datetime.now()}")
print(f"Hostname: {hostname}")
print(f"CPU Usage: {cpu}%")
print(f"Memory Usage: {memory.percent}%")
print(f"Disk Usage: {disk.percent}%")

執行:

python collect_info.py

應該會看到類似:

=== System Information ===

Time: 2026-09-04 09:30:20
Hostname: server01
CPU Usage: 32.5%
Memory Usage: 48.2%
Disk Usage: 36.1%

到這裡,我們已經不用分別輸入好幾個 Linux 指令。

Python 已經可以一次把基本資訊整理出來。

Step 3:找出 CPU 使用率較高的 Process

如果今天收到的是:

High CPU

只知道 CPU 95% 還是不夠。

下一個問題一定是:

到底是哪個 Process 在使用 CPU?

所以繼續修改程式。

import socket
import time
import psutil
from datetime import datetime

hostname = socket.gethostname()

cpu = psutil.cpu_percent(interval=1)
memory = psutil.virtual_memory()
disk = psutil.disk_usage("/")

先記錄 Process

processes = []

for process in psutil.process_iter(["pid", "name"]):
try:
process.cpu_percent(None)
processes.append(process)
except (psutil.NoSuchProcess, psutil.AccessDenied):
pass

等待一秒後再次取得 CPU 使用率

time.sleep(1)

process_list = []

for process in processes:
try:
process_list.append({
"pid": process.pid,
"name": process.name(),
"cpu": process.cpu_percent(None),
"memory": round(process.memory_percent(), 2)
})
except (psutil.NoSuchProcess, psutil.AccessDenied):
pass

CPU 使用率由高到低排序

process_list = sorted(
process_list,
key=lambda x: x["cpu"],
reverse=True
)[:5]

print("=== System Information ===")
print(f"Time: {datetime.now()}")
print(f"Hostname: {hostname}")
print(f"CPU Usage: {cpu}%")
print(f"Memory Usage: {memory.percent}%")
print(f"Disk Usage: {disk.percent}%")

print("\n=== Top CPU Processes ===")

for process in process_list:
print(
f'PID: {process["pid"]} '
f'Name: {process["name"]} '
f'CPU: {process["cpu"]}% '
f'Memory: {process["memory"]}%'
)

再次執行:

python collect_info.py

這次除了系統資訊之外,還會看到:

=== Top CPU Processes ===

PID: 1352 Name: python3 CPU: 42.0% Memory: 3.2%
PID: 921 Name: nginx CPU: 15.3% Memory: 1.5%
PID: 754 Name: sshd CPU: 2.1% Memory: 0.8%

這就開始比較像真正排查問題時需要的資訊了。

Step 4:把結果留下來

如果只顯示在 Terminal,程式結束之後就不太方便後續處理。

所以我希望順便把資料存成 JSON。

加入:

import json

接著整理資料:

report = {
"time": datetime.now().isoformat(),
"hostname": hostname,
"cpu": cpu,
"memory": memory.percent,
"disk": disk.percent,
"top_processes": process_list
}

最後寫入檔案:

with open("incident.json", "w") as file:
json.dump(report, file, indent=4)

執行:

python collect_info.py

目錄裡就會多出:

incident.json

打開:

cat incident.json

可能會看到:

{
"time": "2026-09-04T09:35:12",
"hostname": "server01",
"cpu": 92.4,
"memory": 58.3,
"disk": 36.1,
"top_processes": [
{
"pid": 1352,
"name": "python3",
"cpu": 45.2,
"memory": 3.2
}
]
}

這個 JSON 其實很重要。

因為後面不論是:

存進 Database

送給 API

傳給 AI

都可以直接使用這份資料。

為什麼先整理成 JSON?

如果只是讓 AI 直接去看整台 Server,我覺得範圍太大。

我比較希望流程是:

Server

Python 收集資料

整理成固定格式

再交給下一個系統

這樣後面的程式不用自己猜:

哪一行是 CPU?

哪一行是 Memory?

而是直接取得:

{
"cpu": 92.4,
"memory": 58.3,
"disk": 36.1
}

資料會比較容易處理。

現在和以前有什麼不同?

原本收到 High CPU Alert 之後,可能要自己輸入:

top

再查:

free -h

再看:

df -h

然後自己把資訊拼起來。

現在變成:

python collect_info.py

一次得到:

Hostname
CPU
Memory
Disk
Top CPU Processes

目前看起來只少打幾個指令。

但這一步的真正目的,是為後面的:

自動觸發

做準備。

Day 8 完成

今天我們第一次加入自己寫的程式。

目前完成:

✓ 建立 Python 環境
✓ 使用 psutil 取得系統資訊
✓ 收集 CPU
✓ 收集 Memory
✓ 收集 Disk
✓ 找出高 CPU Process
✓ 將結果儲存成 JSON

目前架構也開始多出自己的程式:

server01

├── Node Exporter
│ ↓
│ Prometheus
│ ↓
│ Grafana

└── Python Collector

incident.json

但現在還有一個很明顯的問題。

這支程式目前還需要自己手動執行:

python collect_info.py

這跟我們要做的「自動化維運」還差一步。


上一篇
Day 7|告警不能只留在 Grafana:把異常通知送出去
下一篇
Day 9|不要再手動執行:讓 Grafana 告警觸發 Python
系列文
30 天打造 AI 自動化維運平台:從監控、告警到故障分析9
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言