寫一個磁碟空間告警腳本 文章首圖

寫一個磁碟空間告警腳本

寫一個磁碟空間告警腳本

在日常的系統維護工作中,磁碟空間不足往往是導致服務中斷、日誌寫入失敗甚至系統崩潰的隱形殺手。當伺服器數量增多時,人工檢查每個節點的磁碟狀態變得既低效又容易遺漏。因此,自動化監控成為 IT 基礎設施管理的必備環節。今天,我們將使用 Bash Shell 撰寫一個簡單但實用的磁碟空間告警腳本,幫助你即時掌握系統健康狀況。

腳本設計邏輯

這個腳本的核心邏輯非常直觀:首先獲取各掛載點(mount point)的使用率,然後與預設的閾值進行比較。如果超過閾值,便透過郵件或即時通訊工具發送警告。為了讓範例更易於測試與理解,我們暫時以標準輸出(stdout)模擬發送動作,並提供如何整合 mailxcurl 發送通知的說明。

完整腳本程式碼

請將以下內容儲存為 disk_alert.sh,並給予執行權限。

#!/bin/bash

# 設定變數
THRESHOLD=90  # 告警閾值,預設為 90%
HOSTNAME=$(hostname)
DATE=$(date '+%Y-%m-%d %H:%M:%S')

# 定義發送通知的函數
send_alert() {
    local mount_point=$1
    local usage=$2

    # 這裡模擬發送通知,實際環境可替換為 mail、slack webhook 或 email
    echo "[$DATE] WARNING: Disk usage on $mount_point is at ${usage}% on $HOSTNAME"

    # 若要發送 Email,請取消下方註解並安裝 mailutils
    # echo "Disk usage on $mount_point is at ${usage}%" | mail -s "Disk Alert: $HOSTNAME" admin@example.com
}

# 檢查 / 掛載點的使用情況
# df -h 顯示人類可讀的容量,df -P 確保輸出格式 POSIX 相容,利於解析
df -P | grep -E "^/dev/sd|^/dev/vd|^/dev/nvme" | while read line; do
    # 解析每行資訊
    filesystem=$(echo "$line" | awk '{print $1}')
    usage=$(echo "$line" | awk '{print $5}' | sed 's/%//')
    mount_point=$(echo "$line" | awk '{print $6}')

    # 檢查 usage 是否為數字且超過閾值
    if [[ "$usage" =~ ^[0-9]+$ ]] && [ "$usage" -ge "$THRESHOLD" ]; then
        send_alert "$mount_point" "$usage"
    fi
done

# 特別檢查根目錄 /,因為有時 df 輸出可能包含 tmpfs 等虛擬檔案系統
root_usage=$(df -P / | tail -1 | awk '{print $5}' | sed 's/%//')
if [[ "$root_usage" =~ ^[0-9]+$ ]] && [ "$root_usage" -ge "$THRESHOLD" ]; then
    # 避免重複發送根目錄警告(若上方 grep 已涵蓋)
    # 此處簡化邏輯,實際可加入去重機制
    send_alert "/" "$root_usage"
fi

echo "Disk check completed at $DATE"

如何執行與測試

在 Ubuntu 22.04 或 Debian 12 上,你可以直接執行該腳本:

chmod +x disk_alert.sh
./disk_alert.sh

為了測試告警功能,你可以手動建立一個大檔案來佔用空間,例如:

# 在 /tmp 下建立一個接近 1GB 的檔案以模擬空間不足
dd if=/dev/zero of=/tmp/bigfile bs=1M count=900

執行腳本後,你應該會看到類似以下的輸出:

[2023-10-27 14:30:00] WARNING: Disk usage on /tmp is at 92% on myserver
Disk check completed at 2023-10-27 14:30:01

常見問題與解決方案

1. 腳本無法正確解析掛載點? df 命令的輸出格式可能因系統版本或掛載類型(如 NFS、Docker overlay)而異。建議使用 df -P 確保輸出符合 POSIX 標準,並使用 awk 精確指定欄位。若發現某些掛載點未被抓出,請檢查 grep 的正則表達式是否涵蓋了該裝置名稱(如 /dev/sda/dev/nvme0n1 等)。

2. 如何整合真實的通知機制? 上述腳本僅輸出到終端。若要實作郵件告警,需安裝 mailutils(Ubuntu/Debian):

sudo apt install mailutils

然後修改 send_alert 函數中的 mail 指令。若使用 Slack 或 Discord,可改用 curl 發送 Webhook 請求:

curl -X POST -H 'Content-type: application/json' \
  --data "{\"text\":\"Disk alert on $HOSTNAME\"}" \
  https://hooks.slack.com/services/YOUR/WEBHOOK/URL

小結

透過這個簡單的 Shell 腳本,我們不僅實現了磁碟空間的自動化檢查,更學習了如何解析 df 輸出以及條件判斷的技巧。建議將此腳本加入 cron 定時任務,例如每小時執行一次,以確保持續監控。隨著經驗累積,你還可以進一步加入歷史趨勢記錄、多閾值警告等級等功能,打造更完善的監控體系。掌握這些基礎腳本技能,將大幅提升你作為 Linux 管理者的效率與應變能力。