本記事はGeminiの出力をプロンプト工学で整理した業務ドラフト(未検証)です。
jqを活用したJSONデータの高度なグループ化と集計の自動化手法
【導入と前提】
APIレスポンスやログ等のJSON配列を、特定のキーで集計・要約してSREのモニタリング効率を向上させます。
- 実行環境: Linux (Ubuntu/RHEL等),
jq1.6以上,curl
【処理フローと設計】
graph TD A["Raw JSON Data"] -->|jq 'group_by'| B["Nested Arrays by Key"] B -->|jq 'map/reduce'| C["Aggregated Object"] C -->|STDOUT| D["Summary Report / Alerting"]
group_by で対象キーごとに配列を分割し、map と reduce を組み合わせて「合計」「平均」「カウント」などの集計処理を一括で行う設計です。
【実装:堅牢な自動化スクリプト】
以下は、クラウドのリソース使用量ログ(JSON)を取得し、サービス単位でコストを集計するスクリプトの例です。
#!/usr/bin/env bash
# ---------------------------------------------------------
# script: aggregate_resource_costs.sh
# description: JSON配列をサービス名でグループ化し、合計コストを算出する
# ---------------------------------------------------------
set -euo pipefail # エラー発生で停止、未定義変数参照禁止、パイプエラーの伝播
trap 'rm -f "$TMP_DATA"' EXIT # 終了時に一時ファイルを確実に削除
# 設定
readonly API_ENDPOINT="https://api.example.com/v1/billing/usage"
readonly TMP_DATA=$(mktemp) # セキュアな一時ファイルの作成
# 1. データ取得(リトライ処理付き)
echo "Fetching usage data..."
curl -s -S -L \
--retry 3 \
--retry-delay 2 \
-H "Authorization: Bearer ${API_TOKEN:-}" \
"$API_ENDPOINT" -o "$TMP_DATA" || { echo "Error: Failed to fetch data"; exit 1; }
# 2. jqによる高度な集計処理
# group_by(.service) : サービス名ごとに配列を分割
# map({...}) : 各グループに対して集計オブジェクトを作成
# reduce : (オプション) 更に大きな集計を行う場合に利用
echo "Aggregating data..."
jq -r '
group_by(.service) |
map({
service: .[0].service,
total_cost: (map(.amount) | add),
count: length,
average_usage: (if length > 0 then (map(.amount) | add) / length else 0 end)
}) |
sort_by(.total_cost) | reverse
' "$TMP_DATA"
# 3. 特定条件でのフィルタリング例 (reduce活用)
# 全サービスの総計を1つのオブジェクトで出す場合
echo "Calculating grand total..."
jq -r '
reduce .[] as $item (0; . + $item.amount) |
{grand_total: .}
' "$TMP_DATA"
【検証と運用】
正常系の確認
スクリプトを実行し、標準出力に整形されたJSONが表示されるか確認します。
./aggregate_resource_costs.sh | jq .
ログ確認と異常検知
システム構成に組み込む場合、systemd-cat を経由させることで journalctl での追跡が可能になります。
# systemdタイマー等で実行する場合のログ確認 journalctl -u resource-aggregation.service -f
【トラブルシューティングと落とし穴】
メモリ消費量:
group_byは入力全体をメモリ上に展開するため、数GB単位の巨大なJSONファイルを扱うとOOM(Out Of Memory)が発生する可能性があります。その場合は、jq -c '.[]'でストリーム処理を検討してください。型変換の失敗: 数値フィールドに文字列が混入している場合、
add演算子がエラーになります。(.amount | tonumber)のように明示的なキャストを推奨します。環境変数の保護:
API_TOKENなどの機密情報はスクリプト内にハードコードせず、exportするか、CI/CDのSecretマネージャーから注入してください。
【まとめ】
運用の冪等性と堅牢性を維持するための3つのポイント:
型安全性の確保:
tonumberやdefault(0)を使い、不正なJSON入力でもスクリプトを落とさない。一時ファイルの管理:
trapコマンドを使用して、異常終了時でもゴミを残さない。リトライロジック: ネットワークの瞬断に備え、
curlの--retryオプションを適切に設定する。

