用 Shell 腳本監控日誌並發送告警 文章首圖

用 Shell 腳本監控日誌並發送告警

用 Shell 腳本監控日誌並發送告警

在系統管理的日常工作中,我們常常需要即時掌握伺服器的運作狀態。當應用程式發生錯誤或資源使用率異常時,若能第一時間收到通知,就能大幅縮短故障排除的時間。雖然 Prometheus 或 ELK Stack 等專業監控工具功能強大,但它們架設複雜且資源消耗較高。對於中小型專案或個人伺服器來說,利用原生 Shell 腳本搭配簡單的日誌輪轉與告警機制,往往是最經濟實用的解決方案。

這篇文章將帶大家撰寫一個完整的 Shell 腳本,實作「監控特定日誌檔案中的 Error 關鍵字,並在發現時透過 Email 發送告警」的功能。

環境準備與依賴安裝

首先,我們需要確保系統具備必要的工具。在 Ubuntu 22.04 或 Debian 12 上,我們需要安裝 mailutils 來發送郵件,並使用 tailgrep 來處理日誌。

打開終端機,執行以下指令安裝依賴套件:

sudo apt update
sudo apt install -y mailutils bsd-mailx

安裝過程中,系統可能會詢問郵件伺服器的設定。若你只是用於本地測試告警機制,選擇「Internet Site」即可,並填入你的網域名稱(例如 localhost)。

實作監控腳本

接下來,我們建立一個名為 log_monitor.sh 的腳本。這個腳本將執行以下邏輯:

  1. 讀取指定的日誌檔案。
  2. 過濾出包含 "ERROR" 或 "CRITICAL" 的行。
  3. 將這些錯誤資訊打包成郵件內容。
  4. 發送給指定的管理員信箱。

請使用編輯器建立檔案:

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 自動化技巧,將是你成為高效系統管理員的重要一步。