構成:指示された9つのセクションを厳守し、技術的な深みを持たせる。
文体:SREらしい、事実に基づいた断定的かつ効率的なトーン。過度な装飾を排し、実用性を重視。
語彙:
べき等性,ステータスコード,パイプライン,クレンジングなど、専門用語を適切に配置。視覚的工夫:コードブロック、Mermaid、箇条書きを活用し、一目で構造を把握可能にする。
本記事はGeminiの出力をプロンプト工学で整理した業務ドラフト(未検証)です。
jqのgroup_byとreduceによるクラウドネイティブ・ログ集計の自動化
【導入と前提】
クラウドネイティブなJSON形式のアクセスログを効率的に集計・分析し、異常検知やレポート作成を自動化する手法を構築します。
OS: Linux (Ubuntu 22.04 LTS / Amazon Linux 2023 推奨)
ツール:
jq(1.6以上),curl,bash(4.4以上)
【処理フローと設計】
graph TD A["外部API/ログファイル"] -->|curl / cat| B["JSON Stream"] B -->|jq: group_by| C["キーごとにグループ化"] C -->|jq: reduce| D["メトリクス集計・計算"] D -->|Output| E["構造化レポート / 通知"]
生データの配列を特定のキー(エンドポイント等)でグルーピングし、各グループ内での統計(リクエスト数、エラー率等)を単一のパスで集計する設計をとります。
【実装:堅牢な自動化スクリプト】
以下は、APIから取得したアクセスログを集計し、エンドポイントごとのエラー率を算出するスクリプト例です。
#!/usr/bin/env bash
# --- 堅牢なシェルスクリプトの設定 ---
set -euo pipefail
IFS=$'\n\t'
# --- 終了時のクリーンアップ処理 ---
trap 'rm -f "$TMP_LOG"' EXIT
# --- 環境変数と定数 ---
API_ENDPOINT="${API_LOG_URL:-"https://api.example.com/v1/logs"}"
TMP_LOG=$(mktemp)
echo "[INFO] ログデータの取得を開始します..."
# --- ログ取得(リトライ処理付き) ---
# -s: 進捗非表示, -S: エラー表示, -L: リダイレクト追従, --retry: 失敗時再試行
curl -sSL --retry 3 --retry-delay 2 "$API_ENDPOINT" -o "$TMP_LOG" || {
echo "[ERROR] データの取得に失敗しました。" >&2
exit 1
}
echo "[INFO] jqによる高度な集集計を実行中..."
# --- jqによるgroup_by & reduceの応用 ---
# 1. group_by(.path): エンドポイントごとに配列を分割
# 2. map(...): 各グループに対して集計を実行
# 3. reduce: 特定条件のカウントを効率化
cat "$TMP_LOG" | jq '
group_by(.path) | map({
path: .[0].path,
total_requests: length,
status_summary: (reduce .[] as $item ({}; .[$item.status | tonumber | tostring] += 1)),
error_count: (map(select(.status >= 400)) | length)
}) | map(. + {
error_rate: (if .total_requests > 0 then (.error_count / .total_requests * 100 | round) else 0 end)
}) | sort_by(.error_rate) | reverse
'
echo "[INFO] 集計が完了しました。"
systemdタイマーによる定期実行設定例
/etc/systemd/system/log-aggregator.service
[Unit] Description=Daily Log Aggregation Task [Service] Type=oneshot ExecStart=/usr/local/bin/log-aggregator.sh User=sre-user Environment="API_LOG_URL=http://internal-log.local/data"
【検証と運用】
正常系の確認
スクリプトを実行し、標準出力にエラー率でソートされたJSONが表示されるか確認します。
bash log-aggregator.sh | jq '.[0]'
ログ確認(systemd経由の場合)
実行履歴やエラーは journalctl で追跡します。
journalctl -u log-aggregator.service --since "1 day ago"
【トラブルシューティングと落とし穴】
メモリ消費:
group_byは全データをメモリ上に展開するため、数GB単位の巨大なJSONを処理する場合は、jq -cによるストリーム処理への切り替えを検討してください。型の一貫性: ステータスコードが文字列と数値で混在している場合、
tonumberで正規化しないとgroup_byやreduceが意図しない動作をします。機密情報の保護: API URLやトークンをスクリプトに直書きせず、環境変数または
systemdのEnvironmentFileを使用してください。
【まとめ】
運用の冪等性を維持するための3つのポイント:
ステートレスな設計: 処理の途中で一時ファイルを作成する場合でも、必ず
trapで削除し、前回実行時の残骸に依存しないようにする。入力のバリデーション:
jqのselectやtry/catchを活用し、不正なJSONレコードが含まれていてもパイプライン全体を停止させない。リトライとタイムアウト: ネットワーク外部要因に備え、
curlの--retryやtimeoutコマンドを組み込み、ハングアップを防止する。

