當 Windows 和 Ubuntu 都開始回傳資料後,我把兩份結果放在一起,馬上碰到新問題:Windows 叫磁碟機代號,Linux 叫掛載點;欄位名稱、錯誤格式也完全不同。如果 Dashboard 每顯示一個數字,都要先問「這台是哪個系統」,後面的功能只會越寫越亂。於是我決定先停下來,把兩邊整理成同一種語言。
每顆磁碟也固定有掛載點、總量、已用量、可用量、使用率與告警等級。collect_host 只管選擇 WinRM 或 SSH,Monitor 和 Web 層只看標準化結果。
這個決定看起來不顯眼,卻讓後面做圖表、通知,甚至加新協定都輕鬆很多。建議文章放一組去識別化 JSON,讀者會更容易理解。
def collect_host(host, execute=run_command):
if host.get("type") == "ssh":
return collect_ssh(host)
if host.get("type") == "winrm":
return collect_winrm(host, execute=execute)
raise CollectionError("Unsupported host type")
Monitor 與 Dashboard 只接收統一結果,不必再次判斷底層協定。
這裡採明確分支比過早建立複雜插件系統更適合目前規模;新增第三種協定時再擴充即可。
for host in (
{"type": "winrm", "host": "192.0.2.10"},
{"type": "ssh", "host": "192.0.2.20"},
):
result = collect_host(host)
print({
"status": result["status"],
"cpu": result.get("cpu_percent"),
"disks": result.get("disks", []),
})
兩種來源最後都能由同一段上層程式讀取,這正是統一快照模型的目的。
初期 Windows 使用磁碟代號、Linux 使用掛載路徑,部分欄位甚至一邊回傳數字、另一邊回傳字串。Dashboard 計算使用率時因此出現型別錯誤,歷史比較也找不到同一顆磁碟。我在 collector 邊界統一欄位名稱與數值型別,並用主機與磁碟組成穩定識別鍵。缺少資料時回傳 None 或明確狀態,而不是補成零,避免「沒有取得資料」被誤認成「使用率 0%」。
今天我看見統一資料模型的價值:它讓圖表、告警和歷史比較能共用相同契約。下一篇會把手動刷新改為背景自動巡檢。