45395 - シコウサクゴ -

Claude Code CLIでサイレント障害調査を自動化する:launchd × --printモードの実践

2026-04-11
AI駆動開発
AI駆動開発
Claude Code
CLI
launchd
自動化
サイレント障害
Last updated:2026-04-12
11 Minutes
2042 Words

データ処理パイプラインの「exit 0だが本来の目的を達成していない」サイレント障害を、Claude Code CLIの--printモードとmacOS launchdを組み合わせて毎朝自動調査する仕組みを構築しました。人間が毎日手動で「サイレント障害はないか調査して」とClaude Codeに依頼していた作業を、AIエージェントに委任した実践記録です。

背景 — 毎日のモグラ叩きをどう自動化するか

データ処理パイプラインの運用で最も厄介なのは、プロセスが正常終了しているのに本来の目的を達成していないサイレント障害です。具体的には以下のような状態を指します。

  • パイプラインの処理件数が0のまま数日経過
  • フォールバック処理に切り替わっているのに検知されない
  • フィルター施策が有効なのにログに出力されない
  • テスト環境が本番データを参照している

従来は毎朝Claude Codeを起動し、「Dry-Run施策でサイレント障害を起こしているものはないか調査して」と手動で依頼していました。これを自動化したいと考えました。

3つのアプローチを比較検討した

A案: シェルスクリプトでデータ収集 → テキストとしてClaude CLIに渡す

Terminal window
1
LOG_DATA=$(tail -50 /tmp/pipeline/*.log)
2
echo "$PROMPT\n$LOG_DATA" | claude -p --model sonnet
  • Claude はツールを使わず、渡されたテキストだけを分析します
  • 最も安全、低コスト($0.02-0.05/日、30秒〜1分)
  • 弱点: 収集対象外のログに異常があっても検知できません

B案: Claudeに自由に調査させる

Terminal window
1
claude -p --dangerously-skip-permissions --model sonnet \
2
"サイレント障害を調査して"
  • 手動調査と同等の動きです。コスト高($0.10-0.30/日、5〜15分)
  • Write/Editも使えてしまうため、意図しないファイル変更のリスクがあります

C案: ブロックリストで書き込み系ツールだけ禁止する(採用)

Terminal window
1
claude -p --dangerously-skip-permissions \
2
--disallowedTools "Write,Edit,NotebookEdit,Agent,Skill,WebFetch,WebSearch" \
3
--model sonnet \
4
"サイレント障害を調査して"
  • Read、Bash(tail/grep/ls等)は使えますが、Write/Editは使えません
  • 手動調査に近い探索力を持ちつつ、書き込み操作は構造的に不可能です
  • コスト中間($0.05-0.15/日、2〜5分)

なぜC案を選んだか

A案B案C案
コスト/日$0.02-0.05$0.10-0.30$0.05-0.15
実行時間30秒〜1分5〜15分2〜5分
未知の障害検知弱い強い中間
安全性最も安全リスクあり安全

A案は「収集したログの範囲内」でしか判断できません。サイレント障害の本質は「どこで問題が起きているかわからない」ことなので、AIが自律的にログを探索できるC案を選びました。

--print--dangerously-skip-permissionsの違い

この2つのフラグはよく混同されますが、役割が異なります。

フラグ役割
--print-p非対話モード。結果をstdoutに出力して終了
--dangerously-skip-permissionsツール実行時の権限確認をスキップ

--printだけだと、Claude がReadやBashを使おうとしたときに権限確認プロンプトが表示されます。しかし非対話モードではプロンプトに応答できないため、ツール実行が拒否されます。--dangerously-skip-permissionsを併用することで、権限確認なしでツールが実行されます。

安全策として--disallowedToolsを併用することで、「権限確認はスキップするが、使えるツール自体を制限する」という設計にしています。

最終的なCLIコマンド

Terminal window
1
claude -p --dangerously-skip-permissions \
2
--disallowedTools "Write,Edit,NotebookEdit,Agent,Skill,WebFetch,WebSearch,TaskCreate,TaskUpdate,TaskStop" \
3
--model sonnet \
4
--max-budget-usd 3.00 \
5
--no-session-persistence \
6
"<プロンプト全文>"

各フラグの意味は以下の通りです。

  • -p: 非対話モード
  • --dangerously-skip-permissions: launchd環境で必須(対話プロンプトを出せない)
  • --disallowedTools: Write/Edit等をブロックし読み取り専用にする
  • --model sonnet: コスト効率重視
  • --max-budget-usd 3.00: コスト上限の安全弁
  • --no-session-persistence: セッション履歴を保存しない(ディスク節約)

設計時の判断: --allowedToolsではなく--disallowedToolsを使う理由

当初はホワイトリスト(--allowedTools)で必要なツールだけ許可する設計でした。しかし、必要なツールをすべて列挙するのは保守が面倒で、新しいツールが追加されたときに更新漏れが起きます。ブロックリスト(--disallowedTools)で書き込み系だけ禁止する方が保守しやすいと判断しました。

3層モニタリングの位置づけ

この自動調査は、既存の監視スタックの最上位レイヤーとして位置づけています。

1
L1 validate_health.sh (06:30) → プロセスは動いているか?
2
L2 monitoring_harness.py (毎時) → パイプラインは流れているか?
3
L3 daily_investigation.py (06:50) → ビジネス目的を達成しているか? ← NEW

L1/L2は「exit 0か」「ログが更新されているか」を見る定量的なチェックです。L3はAIがログの中身を読み、「処理件数が0のまま続いている」「フォールバックしている」「フィルターが機能していない」等の意味のある異常を判断する定性的なチェックです。

調査プロンプトの設計 — AIに何を見させるか

調査プロンプト(investigation_prompt.md、約160行)で8つの観点を指示しています。

  1. 処理件数: entries > 0 か(0が3日以上でアラート)
  2. 監視対象の状態: 条件発火が動作しているか
  3. API通信: 外部APIでエラーがないか
  4. フォールバック不発生: 代替処理に落ちていないか
  5. フィルター動作確認: enabled=trueの施策がログに出ているか
  6. エラーパターン不在: Traceback, ERR-, timeout がないか
  7. DB書き込み正常: 結果テーブルにレコードがあるか
  8. データ整合性: テスト環境が本番データを読んでいないか

プロンプトにはログファイルのパスもすべて記載しています。--add-dirで作業ディレクトリを追加する方法も検討しましたが、CLAUDE.mdがロードされてコンテキストコストが$0.50以上増加するため不採用にしました。

launchdジョブの設定

1
<dict>
2
<key>Label</key>
3
<string>jp.example.daily_investigation</string>
4
<key>ProgramArguments</key>
5
<array>
6
<string>/path/to/python</string>
7
<string>/path/to/daily_investigation.py</string>
8
</array>
9
<key>StartCalendarInterval</key>
10
<dict>
11
<key>Hour</key><integer>6</integer>
12
<key>Minute</key><integer>50</integer>
13
</dict>
14
<key>EnvironmentVariables</key>
15
<dict>
7 collapsed lines
16
<key>HOME</key><string>/Users/username</string>
17
<key>PATH</key>
18
<string>/path/to/python/bin:/Users/username/.local/bin:/usr/local/bin:/usr/bin:/bin</string>
19
</dict>
20
<key>Nice</key><integer>10</integer>
21
<key>ProcessType</key><string>Background</string>
22
</dict>

重要なポイント:

  • PATHに~/.local/binを含めます(claude CLIのインストール先)
  • 実行時刻はL1ヘルスチェック(06:30)の後、朝の業務開始前に設定します
  • Nice=10, ProcessType=Backgroundで低優先度バックグラウンド実行にします

処理フロー

1
06:50 launchd 起動
2
3
├── 調査プロンプト読み込み(8観点 + ログパス + レポート形式)
4
5
├── claude -p --dangerously-skip-permissions \
6
│ --disallowedTools "Write,Edit,..." \
7
│ --model sonnet \
8
│ "<プロンプト全文>"
9
10
│ → Claude CLI が Bash(tail/grep) で自律的にログを読み、判断
11
│ → 約2分で完了
12
13
├── レポートをファイルに保存(7日超は自動削除)
14
15
└── メール送信
1 collapsed line
16
└── 失敗時 → Slack通知にフォールバック

実運用の結果

初回テストの結果は以下の通りです。

  • 実行時間: 136秒
  • コスト: $1.00以内(Maxプラン内なので追加課金なし)
  • 検出した問題: 3件
    • 特定環境で3日間未実行
    • データ鮮度の問題
    • API権限の問題
  • ユニットテスト: 28件全PASS

毎朝メールで調査レポートが届くようになり、手動調査の時間がゼロになりました。

コスト構造

Claude Maxプラン(月額$200)を利用している場合、APIコストは月額に含まれるため追加課金は発生しません--max-budget-usd 3.00はMaxプラン内でのコスト上限として機能し、暴走時の安全弁になります。

Maxプランでない場合は、Sonnetモデルで1日$0.05-0.15程度のAPI費用が発生します。月$1.5-4.5程度です。

まとめ

Claude Code CLIの--printモード + --disallowedToolsの組み合わせにより、**「AIが自律的にログを読んで判断するが、ファイル変更はできない」**という安全な自動調査を実現できました。

ポイントは3つです。

  1. --disallowedToolsで書き込み系ツールをブロックし、読み取り専用にする
  2. 調査プロンプトに具体的な観点とログパスを記載し、AIの探索範囲を適切に絞る
  3. 既存の監視スタック(L1/L2)の上にL3としてAI調査を積む構成にし、役割を明確に分離する

「毎日手動でAIに調査を依頼する」という作業があるなら、それ自体を自動化する価値があります。

Article title:Claude Code CLIでサイレント障害調査を自動化する:launchd × --printモードの実践
Article author:45395
Release time:2026-04-11

記事へのご質問・ご感想をお聞かせください

フィードバックを送る