curlとjqを用いたREST API監視スクリプトの堅牢な自動化設計

Tech

{ “role”: “SRE/DevOps Engineer”, “style”: “Technical, Practical, Robust, Explanatory”, “formatting”: “Markdown with Mermaid, Code blocks with comments”, “language”: “Japanese” }

本記事はGeminiの出力をプロンプト工学で整理した業務ドラフト(未検証)です。

curlとjqを用いたREST API監視スクリプトの堅牢な自動化設計

【導入と前提】

APIの死活監視とレスポンスの妥当性検証を自動化し、障害検知時の初動を迅速化するシェルスクリプトのテンプレートを提供します。

  • 前提OS: Linux (Ubuntu 22.04 LTS / RHEL 9 等)

  • 必須ツール: curl (v7.71.0以降推奨), jq (v1.6以降)

【処理フローと設計】

graph TD
    A["開始: 定期実行"] --> B{"curl実行: APIリクエスト"}
    B -- HTTP 200以外 --> C["エラーログ出力 & 終了"]
    B -- HTTP 200 --> D["jq: レスポンス検証"]
    D -- スキーマ/値の異常 --> E["警告通知 & 終了"]
    D -- 正常 --> F["ステータス更新 & 一時ファイル削除"]
    F --> G["終了"]

このフローでは、HTTPプロトコルレベルの成否判定と、jqによるビジネスロジック(JSONペイロードの中身)の検証を分離し、多段階でエラーをトラップします。

【実装:堅牢な自動化スクリプト】

1. 監視実行スクリプト (api_monitor.sh)

#!/usr/bin/env bash

# set -e: エラー発生時に即座に終了


# set -u: 未定義変数の参照をエラーとする


# set -o pipefail: パイプ途中のエラーを戻り値に反映させる

set -euo pipefail

# 設定項目

API_URL="https://api.example.com/v1/health"
TEMP_FILE=$(mktemp /tmp/api_response.XXXXXX.json)
RETRY_COUNT=3
TIMEOUT_SEC=10

# 終了時に一時ファイルを確実に削除する

trap 'rm -f "$TEMP_FILE"' EXIT

echo "[INFO] API検証開始: ${API_URL}"

# 1. curlによるデータ取得


# -s: 進捗非表示, -S: エラー表示, -L: リダイレクト追従


# -f: HTTPエラー(4xx/5xx)時に異常終了させる


# --retry: ネットワーク一時不全に対するリトライ

if ! curl -sSLf \
    --connect-timeout "$TIMEOUT_SEC" \
    --retry "$RETRY_COUNT" \
    --retry-delay 2 \
    -o "$TEMP_FILE" \
    "$API_URL"; then
    echo "[ERROR] APIへの接続に失敗しました、またはHTTPステータスエラーです。" >&2
    exit 1
fi

# 2. jqによるJSONペイロードの検証


# .status が "UP" かどうかをチェック


# jq -e は結果が false または null の場合に終了コード 1 を返す

if ! jq -e '.status == "UP"' "$TEMP_FILE" > /dev/null; then
    echo "[ERROR] APIステータスが 'UP' ではありません。" >&2
    echo "レスポンス内容: $(cat "$TEMP_FILE")" >&2
    exit 1
fi

# 3. 特定の値の抽出例(例: バージョン情報の記録)

VERSION=$(jq -r '.version // "unknown"' "$TEMP_FILE")
echo "[SUCCESS] APIは健全です (Version: ${VERSION})"

2. systemdによる定期実行設定

/etc/systemd/system/api-check.service (サービス定義)

[Unit]
Description=API Health Check Service
After=network.target

[Service]
Type=oneshot
ExecStart=/usr/local/bin/api_monitor.sh
User=monitor-user
Group=monitor-user

[Install]
WantedBy=multi-user.target

/etc/systemd/system/api-check.timer (タイマー定義: 5分ごと)

[Unit]
Description=Run API Health Check every 5 minutes

[Timer]
OnCalendar=*:0/5
Persistent=true

[Install]
WantedBy=timers.target

【検証と運用】

正常系の確認

スクリプトを手動実行し、標準出力に [SUCCESS] が表示されること、および終了コードが 0 であることを確認します。

bash api_monitor.sh
echo $?

異常系の確認(ログ確認)

systemd 経由で実行した場合、エラーログは journalctl で集約管理されます。

# 特定のサービスのエラーログを直近1時間分表示

journalctl -u api-check.service --since "1 hour ago"

【トラブルシューティングと落とし穴】

  1. 権限問題: mktemp で作成するディレクトリ(/tmp)に、実行ユーザーの書き込み権限があるか確認してください。systemd で実行する場合は User= に指定したユーザーの権限が適用されます。

  2. 環境変数の漏洩: APIキーなどをスクリプトに直書きせず、systemdEnvironmentFile= や、Vault等の外部管理ツールから読み込むように設計してください。

  3. jqのバージョン差異: 古い jq (v1.5未満) では一部の演算子の挙動が異なる場合があります。コンテナイメージやOSパッケージのバージョンを固定することを推奨します。

【まとめ】

運用の冪等性と堅牢性を維持するための3つのポイント:

  1. パイプラインの安全確保: set -o pipefail を使い、curl の失敗を jq が隠蔽しないようにする。

  2. リソースのクリーンアップ: trap コマンドで、スクリプトが異常終了しても一時ファイルが残らないように制御する。

  3. リトライロジックの内包: 一時的なネットワークの揺らぎでアラートを発報させないよう、curl 自体のリトライオプションを適切に活用する。

ライセンス:本記事のテキスト/コードは特記なき限り CC BY 4.0 です。引用の際は出典URL(本ページ)を明記してください。
利用ポリシー もご参照ください。

コメント

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