用 Shell 腳本監控日誌並發送告警
在系統管理的日常工作中,我們常常需要即時掌握伺服器的運作狀態。當應用程式發生錯誤或資源使用率異常時,若能第一時間收到通知,就能大幅縮短故障排除的時間。雖然 Prometheus 或 ELK Stack 等專業監控工具功能強大,但它們架設複雜且資源消耗較高。對於中小型專案或個人伺服器來說,利用原生 Shell 腳本搭配簡單的日誌輪轉與告警機制,往往是最經濟實用的解決方案。
這篇文章將帶大家撰寫一個完整的 Shell 腳本,實作「監控特定日誌檔案中的 Error 關鍵字,並在發現時透過 Email 發送告警」的功能。
環境準備與依賴安裝
首先,我們需要確保系統具備必要的工具。在 Ubuntu 22.04 或 Debian 12 上,我們需要安裝 mailutils 來發送郵件,並使用 tail 和 grep 來處理日誌。
打開終端機,執行以下指令安裝依賴套件:
sudo apt update
sudo apt install -y mailutils bsd-mailx
安裝過程中,系統可能會詢問郵件伺服器的設定。若你只是用於本地測試告警機制,選擇「Internet Site」即可,並填入你的網域名稱(例如 localhost)。
實作監控腳本
接下來,我們建立一個名為 log_monitor.sh 的腳本。這個腳本將執行以下邏輯:
- 讀取指定的日誌檔案。
- 過濾出包含 "ERROR" 或 "CRITICAL" 的行。
- 將這些錯誤資訊打包成郵件內容。
- 發送給指定的管理員信箱。
請使用編輯器建立檔案:
nano log_monitor.sh
並貼上以下程式碼:
#!/bin/bash
# =================配置區=================
# 要監控的日誌檔案路徑
LOG_FILE="/var/log/myapp/application.log"
# 告警接收者的電子郵件地址
ALERT_EMAIL="admin@example.com"
# 發件人顯示名稱
SENDER_NAME="Log Monitor"
# 檢查日誌檔案是否存在
if [ ! -f "$LOG_FILE" ]; then
echo "錯誤:日誌檔案 $LOG_FILE 不存在" >&2
exit 1
fi
# =================主要邏輯=================
# 使用 grep 搜尋 ERROR 或 CRITICAL 關鍵字
# -i: 不區分大小寫
# -n: 顯示行號
# -E: 使用擴展正則表達式
ERROR_LINES=$(grep -iE "ERROR|CRITICAL" "$LOG_FILE" | tail -n 5)
# 如果沒有找到錯誤,則結束腳本
if [ -z "$ERROR_LINES" ]; then
exit 0
fi
# 構建郵件主旨
SUBJECT="[告警] 伺服器日誌發現異常 - $(date '+%Y-%m-%d %H:%M:%S')"
# 構建郵件內容
BODY="偵測到以下日誌錯誤,請盡快檢查:\n\n${ERROR_LINES}\n\n請登入伺服器查看詳細資訊。"
# 發送郵件
# 使用 mail 指令發送
echo -e "$BODY" | mail -s "$SUBJECT" -r "$SENDER_NAME <$ALERT_EMAIL>" "$ALERT_EMAIL"
# 記錄本次告警已發送,避免重複告警(可選)
echo "[$(date)] Alert sent to $ALERT_EMAIL" >> /var/log/log_monitor_alert.log
exit 0
儲存後,請給予腳本執行權限:
chmod +x log_monitor.sh
自動化執行
為了讓監控持續運作,我們可以使用 cron 定時任務來執行這個腳本。例如,每 5 分鐘檢查一次。
編輯 crontab:
crontab -e
加入以下行:
*/5 * * * * /path/to/your/log_monitor.sh
請將 /path/to/your/ 替換為腳本實際存放的路徑。這樣系統就會每五分鐘自動掃描一次日誌,若有異常便會立即通知你。
常見問題與解決
1. 郵件無法發送或進入垃圾郵件匣
許多雲端主機商(如 AWS EC2、Google Cloud)預設會封鎖 25 號端口以防止垃圾郵件。如果腳本執行後沒有收到郵件,請檢查 /var/mail/root 或 /var/log/mail.log 的錯誤訊息。建議使用 SendGrid、Mailgun 等第三方 SMTP 服務,或改用 curl 呼叫 Slack/Telegram Webhook 來發送告警,這樣更穩定且不易被攔截。
2. 日誌檔案過大導致效能問題
如果日誌檔案非常大(例如數 GB),直接對其進行 grep 可能會消耗大量 CPU 資源。建議在監控前,先確認日誌是否已正確配置 logrotate 進行輪轉。此外,腳本中的 tail -n 5 只抓取最後 5 筆錯誤,這能有效減少郵件內容的大小,但請注意,這可能會遺漏較早發生的錯誤。若需完整追蹤,可考慮將錯誤寫入臨時文件再發送。
小結
透過這個簡單的 Shell 腳本,我們實現了基本的日誌監控與告警功能。雖然它不如專業監控平台強大,但其輕量、易於維護的特性,非常適合初學者入門或小型環境使用。隨著技術的精進,你可以進一步擴展這個腳本,例如加入對 CPU 使用率的檢查、整合 Telegram Bot API,或是將告警資訊寫入資料庫。掌握基礎的 Shell 自動化技巧,將是你成為高效系統管理員的重要一步。