死活監視スクリプトにログ保存機能を追加!過去の監視データを活用する

これまでに紹介した死活監視スクリプトに、新たにログ保存機能を追加しました。この機能を利用すると、監視結果を記録として残すことができ、運用状況の確認や分析が可能になります。この記事では、追加した機能の詳細や実装コードを詳しくご紹介します。

背景

以前の死活監視スクリプトでは、監視結果をリアルタイムで通知する機能のみでした。しかし、次のような課題がありました。

  1. 過去の監視結果を確認できない
    通知された内容を記録していないため、障害の履歴や稼働率を振り返ることができませんでした。
  2. 監視結果を分析しづらい
    データが蓄積されていないため、稼働状況や障害発生の傾向を分析することができませんでした。

これらの課題を解決するため、監視結果をCSV形式で保存する機能を追加しました。

機能のポイント

1. ログの保存形式

監視結果は、CSV形式で記録します。この形式にすることで、以下のメリットがあります。

  • ExcelやGoogleスプレッドシートで簡単に開ける
  • プログラムで読み込んで加工・分析が可能

2. ディレクトリ構成

監視対象の会社ごとにサブディレクトリを作成し、日付単位でログを分割保存します。

保存先例

logs/
├── companyA/
│   ├── monitor_results_20241114.csv
│   ├── monitor_results_20241115.csv
├── companyB/
│   ├── monitor_results_20241114.csv
│   ├── monitor_results_20241115.csv

3. 保存データの内容

監視結果には以下の情報を保存します。

項目説明
日時監視結果の記録日時
サイト監視対象のURL
状態サイトの状態 (正常/異常)
ステータスコードHTTPステータスコード

ログの内容例

日時,サイト,状態,ステータスコード
2024-11-14 15:00:00,https://example.com/,正常に稼働中,200
2024-11-14 15:00:00,https://example.org/,ダウンしています,503

実装コード

以下は、ログ保存機能を追加した死活監視スクリプトの完全なコードです。設定情報やURL、メールアドレスなどはダミー情報に変更しています。

#!/bin/bash

# パラメーターで指定された会社名を取得
company="$1"

# 配列の宣言
declare -A sites

# 設定ファイルのパスを作成
config_file="$(dirname "$0")/config_${company}.sh"

# 設定ファイルが存在するかチェック
if [[ ! -f "$config_file" ]]; then
    echo "エラー: 設定ファイル '${config_file}' が見つかりません。"
    exit 1
fi

# 設定ファイルの読み込み
source "$config_file"

# 実行開始時間の取得
start_time=$(date "+%Y-%m-%d %H:%M:%S")
log_date=$(date "+%Y%m%d")

# 保存ディレクトリ (logs/company 毎のディレクトリを作成)
log_dir="$(dirname "$0")/logs/$company"
mkdir -p "$log_dir"

# 保存ファイルのパス (日付単位で分割保存)
save_file="$log_dir/monitor_results_${log_date}.csv"

# 初回実行時にヘッダーを追加
if [[ ! -f "$save_file" ]]; then
    echo "日時,サイト,状態,ステータスコード" > "$save_file"
fi

# メール通知関数
send_email() {
    local site=$1
    local emails=$2
    local status_code=$3
    local status_message=$4
    local subject="【サイト監視】$site は$status_message (HTTPステータスコード: $status_code)"
    local body="【サイト監視結果】\n\n日時: $start_time\n\n対象サイト: $site\n状態: $status_message\nHTTPステータスコード: $status_code\n\nご確認ください。"

    echo -e "$body" | mail -s "$subject" -b "bcc@example.com" "$emails"
}

# Chatwork 通知関数
send_chatwork_notification() {
    local message=$1
    local room_id=$2
    curl -X POST -H "X-ChatWorkToken: $chatwork_api_token" \
        -d "body=$message" \
        "https://api.chatwork.com/v2/rooms/$room_id/messages"
}

# Slack 通知関数
send_slack_notification() {
    local message=$1
    curl -X POST -H 'Content-type: application/json' --data "{\"text\": \"$message\"}" "$slack_webhook_url"
}

# サマリー通知用の変数
summary_subject="【サイト監視サマリー】全サイトの状態レポート"
summary_body="【サイト監視結果サマリー】\n\n日時: $start_time\n\n監視結果:\n\n"
alert_needed=false
alert_summary_body="【サイト監視異常通知】\n\n日時: $start_time\n\n異常検知されたサイト:\n\n"

# サイトの死活監視
declare -A processed

for key in "${!sites[@]}"; do
    # site_keyをキーから抽出
    site_key="${key%%.*}"

    # 同じサイトを一度だけ処理
    if [[ -z "${processed[$site_key]}" ]]; then
        url="${sites[$site_key.url]}"
        emails="${sites[$site_key.email]}"
        email_notify="${sites[$site_key.notify]}"
        processed[$site_key]=1  # 処理済みマークを設定

        # curlを使ってサイトのHTTPステータスコードを取得
        status_code=$(curl -o /dev/null -s -w "%{http_code}" "$url")

        # ステータスコードによる通知内容の判断
        if [[ "$status_code" == "200" || "$status_code" == "301" || "$status_code" == "302" ]]; then
            status_message="正常に稼働中"
        else
            if [[ "$status_code" == "503" ]]; then
                status_message="サービスが一時的に利用できません"
            else
                status_message="ダウンしています"
            fi
        fi

        # ログ保存
        echo "$start_time,$url,$status_message,$status_code" >> "$save_file"

        # 必要に応じて通知
        if [[ "$email_notify" == "true" && -n "$emails" ]]; then
            send_email "$url" "$emails" "$status_code" "$status_message"
        fi

        # 異常検知時の追加
        if [[ "$status_message" != "正常に稼働中" ]]; then
            alert_needed=true
            alert_summary_body+="$url\n  状態: $status_message\n  ステータスコード: $status_code\n\n"
        fi

        # サマリーへの追加
        summary_body+="$url\n  状態: $status_message\n  ステータスコード: $status_code\n\n"
    fi
done

# サマリー通知の送信 (メール)
echo -e "$summary_body" | mail -s "$summary_subject" -b "$bcc_email" "$bcc_email"

# サマリー通知の送信 (Chatwork)
encoded_summary_body=$(echo -e "$summary_body" | sed ':a;N;$!ba;s/\n/%0A/g')
send_chatwork_notification "$encoded_summary_body" "$chatwork_room_id"

# サマリー通知の送信 (Slack)
slack_message="【サイト監視サマリー】\n\n日時: $start_time\n\n監視結果:\n\n$summary_body"
send_slack_notification "$slack_message"

# 異常が検知された場合の通知
if [ "$alert_needed" = true ]; then
    echo -e "$alert_summary_body" | mail -s "【サイト監視異常通知】異常が検知されました" "$alert_email"
    encoded_alert_summary_body=$(echo -e "$alert_summary_body" | sed ':a;N;$!ba;s/\n/%0A/g')
    send_chatwork_notification "$

encoded_alert_summary_body" "$alert_chatwork_room_id"
    slack_alert_message="【サイト監視異常通知】\n\n日時: $start_time\n\n異常検知されたサイト:\n\n$alert_summary_body"
    send_slack_notification "$slack_alert_message"
fi

まとめ

ログ保存機能を追加することで、監視結果を記録として残し、運用効率が向上します。また、今後はこれらのログを可視化するダッシュボードを作成し、さらなる効率化を目指します。

必要に応じて、この記事の内容を参考にしてスクリプトを改修してください!

コメント

タイトルとURLをコピーしました