author: SRE_Consultant style: technical_documentation_sre tools: [jq, bash, systemd] knowledge_level: advanced 本記事はGeminiの出力をプロンプト工学で整理した業務ドラフト(未検証)です。
高度なjqフィルタリングによるシステムメトリクスの集計・自動化
【導入と前提】
大量のJSON形式ログやAPIレスポンスを、group_byとreduceを用いて高速に集計し、SREの意思決定を支援する堅牢なスクリプトを構築します。
OS: GNU/Linux (Ubuntu/RHEL)
Tool: jq 1.6+, curl, bash 4.4+
【処理フローと設計】
graph TD A["JSON Data Source"] -->|curl/cat| B["jq: group_by"] B -->|Sort & Group| C["jq: reduce/map"] C -->|Aggregate/Summary| D["Structured Report"] D -->|Alert/Log| E["Monitoring System"]
group_by は内部的にソートを行うため、対象の配列が巨大な場合はメモリ消費に注意が必要です。一方、reduce は単一パスで集計を行うため、パフォーマンスを最大化する際に有効です。これらを組み合わせることで、特定のキー(例:HTTPステータス、インスタンスID)ごとの統計情報を抽出します。
【実装:堅牢な自動化スクリプト】 以下は、分散されたアクセスログ(JSON)を読み込み、ステータスコードごとにリクエスト数を集計するテンプレートスクリプトです。
#!/usr/bin/env bash
# --- 安全のためのシェルオプション ---
# -e: エラー発生時に即座に終了
# -u: 未定義変数の参照時にエラー
# -o pipefail: パイプラインの途中のエラーを拾う
set -euo pipefail
# 一時ファイル管理用のtrap
TMP_DATA=$(mktemp)
readonly TMP_DATA
trap 'rm -f "${TMP_DATA}"' EXIT
# --- 設定 ---
# ダミーデータの生成(実際はAPIリクエストやログファイル)
cat << 'EOF' > "${TMP_DATA}"
[
{"status": 200, "latency": 120, "path": "/api/v1"},
{"status": 500, "latency": 500, "path": "/api/v1"},
{"status": 200, "latency": 150, "path": "/health"},
{"status": 404, "latency": 50, "path": "/unknown"},
{"status": 500, "latency": 450, "path": "/api/v2"}
]
EOF
echo "--- 1. group_by による集計例 (ステータス別カウント) ---"
# group_by(field): 指定したキーで配列をネストされた配列に分割
# map({key: .[0].field, value: length}): グループごとの個数を計算
jq -r '
group_by(.status)
| map({
"status": .[0].status | tostring,
"count": length
})
' "${TMP_DATA}"
echo "--- 2. reduce による高度な統計計算 (レイテンシ合計) ---"
# reduce: 配列を一つずつ処理し、アキュムレータ(acc)に結果を蓄積
# リトライ処理や条件分岐を含む集計に最適
jq -r '
reduce .[] as $item ({};
.[$item.status | tostring] += {
"count": 1,
"total_latency": $item.latency
} |
.[$item.status | tostring].count += 0 # 初期化補助
)
' "${TMP_DATA}"
# --- 実戦的なAPI取得と集計の例 ---
# curl -L: リダイレクト追従, -s: 進捗非表示, --retry: 失敗時の再試行
# URL="https://api.example.com/metrics"
# curl -L -s --retry 3 "${URL}" | jq 'group_by(.severity) | map({(.[0].severity): length}) | add'
【検証と運用】
正常系の確認: スクリプトを実行し、標準出力にステータスコード別のJSONオブジェクトが返ることを確認します。
./aggregate_metrics.sh | jq -e '.[] | has("status")'システムログの監視: 本処理をsystemdタイマーで実行する場合、以下のコマンドで実行ログとエラーを確認します。
journalctl -u json-aggregator.service -f
【トラブルシューティングと落とし穴】
メモリ制約:
group_byは全データをメモリに展開しソートします。数GB単位のJSONを扱う場合は、jq --streamオプションの使用や、事前にsplitコマンドで分割して処理することを検討してください。型の一貫性:
group_byのキーに数値と文字列が混在すると、予期しないグループ化が行われます。必ずtostringやtonumberで正規化してください。権限: 出力先のディレクトリへの書き込み権限や、一時ファイル
/tmpの容量不足に注意してください。
【まとめ】 運用の冪等性を維持するための3つのポイント:
入力チェック:
jq処理前に、入力が空でないか、正当なJSON形式かを確認する。Atomicな書き出し: 結果をファイルに保存する際は、一時ファイルに書き出した後
mvで置換し、中途半端な状態のファイルを生成しない。エラーハンドリング: パイプライン内で
jqがエラーを吐いた場合、set -o pipefailによりスクリプトを停止させ、不正なデータが後続工程に流れるのを防ぐ。

