コドモン Product Team Blog

株式会社コドモンの開発チームで運営しているブログです。エンジニアやPdMメンバーが、プロダクトや技術やチームについて発信します!

AIを使ったら、アラート調査がターミナルだけで完結するようになった

こんにちは、新規事業のプロダクト開発を担当している杉山です。

今回は、障害調査やエラー分析をClaude Codeを活用し、迅速化・精度向上させる方法について紹介します。Datadog MCP、AWS CLI、GitHub CLI(ghコマンド)などを組み合わせることで、ターミナルから一歩も出ることなく、Slackに来たアラート通知の原因特定からコード修正の提案まで一気通貫で行えるようになりました。

本記事は、AIを活用した障害調査や開発ワークフローの効率化に興味のあるエンジニアの方を中心に、お役に立てればと思い書いた記事です。

Slackにアラートが来た。さて、どうする?

私たちの新規事業のサービスでは、画像のサマリー生成やリサイズといった重い処理をSQSキューを使って非同期に実行しています。ある日、その画像処理キューに対して、SlackにDatadogからこのような通知が来ました。

Triggered: [SQS] ApproximateAgeOfOldestMessage on image-processing-queue

image-processing-queue にて、ApproximateAgeOfOldestMessage が上昇しています。

Metric value: 41.0
Tags: queuename:image-processing-queue

ApproximateAgeOfOldestMessageは、SQSキューの中で最も古いメッセージがどれだけの時間滞留しているかを示すメトリクスです。この値が上昇しているということは、キューに入ったメッセージが正常に消費されず、処理が詰まっている可能性を意味します。つまり、コンシューマー側で何らかの問題が起きているサインです。

以前であれば、ここからの動きはこうでした。

  1. Datadogを開いてログを検索する
  2. 関連するトレースを辿る
  3. AWSコンソールでSQSのキューの状態を確認する
  4. DLQにメッセージが溜まっていないか見る
  5. コードを読んで原因を推測する

これらを全てブラウザの複数タブを行き来しながら手作業で行っていました。

今はこうです。

Slackからエラーの通知が来たので、DatadogやAWSを見に行って、原因を特定してください。

[ここにslackの通知内容をそのまま貼り付ける]

Claude Codeにこれを投げるだけです。

実際の調査:DLQ蓄積の原因特定

具体的にClaudeがどう動くのか、実際の事例をもとに説明します。

先述の画像処理パイプラインでは、各キューにDLQ(Dead Letter Queue)が設定されていて、3回処理に失敗したメッセージはDLQに移動します。

通知内容を渡されたClaudeは、以下の順で自動的に調査を進めてくれました。

Step 1: Datadogでエラーログを特定

まずDatadog MCPを使ってログを検索します。search_datadog_logsimage-processing-queueに関連するエラーを探し、スタックトレースを含むログを発見します。

ここで面白いのが、Claudeはログの中身を読んで「これは特定の例外だ」「特定のメソッドで発生している」といった解析までやってくれることです。単にログを出力するだけでなく、エラーの意味を理解した上で次のステップに進みます。

Step 2: AWS CLIでDLQの状態を確認

次に、AWS CLIでDLQにメッセージが溜まっていないか確認します。

aws sqs get-queue-attributes \
  --queue-url https://sqs.ap-northeast-1.amazonaws.com/xxx/image-processing-dlq \
  --attribute-names ApproximateNumberOfMessages \
  --profile dev --region ap-northeast-1

DLQにメッセージが存在していることを確認すると、さらに中身を読みに行きます。

aws sqs receive-message \
  --queue-url https://sqs.ap-northeast-1.amazonaws.com/xxx/image-processing-dlq \
  --max-number-of-messages 10 \
  --visibility-timeout 0 \
  --profile dev --region ap-northeast-1

--visibility-timeout 0 を指定しているのは、メッセージを「覗き見」するだけで消費しないためです。このあたりのオプションもClaudeが自動で判断してくれます。

Step 3: コードを読んで原因を特定

DLQのメッセージ内容とエラーログの情報をもとに、Claudeは該当するListenerのコードを読みに行きます。

@SqsListener(value = ["\${aws.sqs.queue-urls.image-processing}"])
fun handle(message: QueueMessage) {
    runBlocking {
        processingUseCase.execute(message).fold(
            ifLeft = { error ->
                throw error.cause ?: RuntimeException("Failed to process message")
            },
            ifRight = {
                logger.info("Processing task completed: $message")
            }
        )
    }
}

ListenerがEitherfoldパターンでエラーハンドリングをしていること、例外がスローされるとSQSのRedrivePolicy(maxReceiveCount=3)によって自動的にDLQに移動すること、そしてその根本原因が画像処理ロジック内のバグにあること——ここまでを一連の流れで特定してくれます。

Step 4: 調査サマリーの出力

最後に、調査結果を構造化してまとめてくれます。

## 調査サマリー

### 問題概要
image-processing-queue で ApproximateAgeOfOldestMessage が上昇。
画像処理ロジックのバグによりメッセージ処理が失敗し、DLQに蓄積。

### 根本原因
画像処理の前処理で特定の入力パターンに対して例外が発生。

### 推奨アクション
1. 該当する処理ロジックを修正
2. 修正をデプロイ
3. デプロイ後、DLQからソースキューへ再エンキュー:
   aws sqs start-message-move-task \
     --source-arn "arn:aws:sqs:..." \
     --destination-arn "arn:aws:sqs:..."

ARNもAWS CLIでインフラリソースの詳細を見に行くので、完全な再エンキューのコマンドまで提案してくれるのがポイントです。あとは修正してデプロイして、提示されたコマンドを実行するだけ。

Skills による調査の自動化

この体験を支えているのが、Claude Codeの Skills 機能です。Skillsは、特定のタスクに対する手順書のようなもので、Claudeにドメイン知識と調査フローを事前に教えておくことができます。

私は調査用のSkillsを グローバルプロジェクトレベル で分けて管理しています。

グローバルSkills(~/.claude/skills/

Datadogは複数のサービスを横断してログやトレースを保持しているため、特定のプロジェクトに紐づけるのではなく、個人のグローバルな設定として持っています。

  • investigate: Datadog + AWS を横断する統合調査スキル
  • investigate-dd: Datadog のみで調査するスキル
  • investigate-aws: AWS CLI のみで調査するスキル

たとえば統合調査スキル(investigate)の定義ファイルは、以下のような感じになっています。

---
name: investigate
description: Datadog と AWS を横断してログ・エラーを調査する統合スキル。障害調査、エラー分析、パフォーマンス問題の原因特定に使用。
model: opus
argument-hint: "<調査対象の説明> [--profile <aws-profile>]"
---

description はClaudeがSkillを自動選択する際の判断材料になります。model でスキルごとに使用するモデルを指定でき、複雑な横断調査にはopusを、単体サービスの調査(investigate-dd, investigate-aws)にはsonnetを使い分けています。

スキル本体には、調査フローが4つのフェーズで定義されています。

Phase 1: 認証チェック(Datadog MCP / AWS SSO)
Phase 2: Datadog 調査(ログ → トレース → モニター → サービス依存関係 → メトリクス)
Phase 3: AWS 調査(CloudWatch Logs → リソース状態 → メトリクス/アラーム)
Phase 4: サマリー出力

具体的にどの程度の粒度で定義しているのか、Phase 2 の Datadog 調査部分を抜粋します。

### Phase 2: Datadog 調査

以下の順に、関連する情報を収集する。各ステップで得られた情報を元に次の調査を絞り込む。

1. **ログ検索** (`search_datadog_logs` / `analyze_datadog_logs`)
   - 調査対象に関連するキーワード・サービス名・エラーメッセージでログを検索
   - 時間範囲を絞り込み、エラーパターンを特定

2. **トレース/スパン** (`get_datadog_trace` / `search_datadog_spans`)
   - エラーに関連するトレースを取得し、どのサービス・エンドポイントで問題が発生しているか特定
   - レイテンシやエラー率の異常を確認

3. **モニター/インシデント** (`search_datadog_monitors` / `search_datadog_incidents`)
   - 関連するモニターのアラート状態を確認
   - 進行中のインシデントがあれば詳細を取得

4. **サービス依存関係** (`search_datadog_services` / `search_datadog_service_dependencies`)
   - 影響を受けるサービスの上流・下流を把握
   ...

各ステップにMCPのツール名が明記されているので、Claudeはどのツールを使って何を調べるべきかを具体的に把握できます。「各ステップで得られた情報を元に次の調査を絞り込む」という指示が、先ほどの事例で見たような段階的な原因特定を駆動しています。

Claudeはこのフローに従って、体系的に調査を進めてくれます。調査結果は「問題概要 → 根本原因 → 影響範囲 → タイムライン → 推奨アクション」という形式でまとめて出力されます。

Skillsの中では、利用可能なAWSプロファイルの一覧を動的に取得する仕組みも入れています。このファイルの中身にはシークレットは入っていません。profileごとに向き先の設定が入っているだけです。

## 利用可能な AWS プロファイル
!cat ~/.aws/credentials 2>/dev/null | grep '^\[' | tr -d '[]'

これにより、Claudeは実行時にどのプロファイルが使えるのかを把握した上で、ユーザーに選択を促すことができます。

プロジェクトレベルSkills

各リポジトリの .claude/skills/ に配置しています。アーキテクチャのガイドライン、テストの書き方、ドメイン固有の知識など、そのプロジェクトに特化した情報を持たせています。調査の過程でコードを読む際に、これらのSkillsが文脈を補ってくれます。

CLAUDE.mdに特別な指示は不要

ここで強調しておきたいのが、CLAUDE.mdには調査のための特別な指示を一切入れていないということです。

Skillsさえ定義しておけば、Claudeが状況に応じて適切なSkillを自動的に選んで実行してくれます。「Datadogを見に行って原因を特定してください」と言えば、Claudeは自分でinvestigateinvestigate-ddのSkillを見つけて、そこに書かれた手順に従って調査を進めてくれます。

CLAUDE.mdはあくまでプロジェクトのコーディングガイドラインやアーキテクチャ情報を記載する場所として使っています。調査の手順はSkillsに集約し、関心を分離しています。この分離により、調査フローを改善したいときはSkillsだけを更新すればよく、CLAUDE.mdを肥大化させずに済みます。

コードを横断的に見る

調査の過程では、コードを読んで原因を特定する場面が頻繁にあります。ここで重要なのが、複数リポジトリのコードを横断的に見られる環境を用意しておくことです。

私は複数のリポジトリをまとめた ~/Dev ディレクトリでClaude Codeを実行しています。ここにはプロジェクトに必要な複数のリポジトリがまとめて配置されています。

~/Dev/
├── repo-a/           # メインのバックエンドサービス(モノレポ)
├── repo-b/           # モバイルアプリ
├── repo-c/           # インフラ(Terraform)
└── ...

バックエンドのコードもインフラ定義もモバイルも全て同じ親ディレクトリに置いているので、Claudeはアラートが来たサービスのコードだけでなく、関連するサービスや共通ライブラリ、インフラの定義まで横断的に調査対象にできます。ローカルにリポジトリがない場合でも、ghコマンド経由でリモートのコードを読みに行くこともできます。重要なのは Claudeが調査の文脈で必要なコードに自由にアクセスできる状態を作っておくこと です。

先ほどの事例でも、ClaudeはSQSのListener実装からビジネスロジック、さらにはTerraformで定義されたインフラ構成まで、複数のプロジェクトやリポジトリを横断的に読んでいます。「このキューのvisibilityTimeoutは300秒でmaxReceiveCountは3だから、最大15分でDLQに移動する」といった情報も、Terraformの定義を読んで自分で把握してくれます。

Datadog MCPで最後のワンマイルがつながった

ここまでの話で一番のブレイクスルーは、Datadog MCPの登場でした。

Datadog MCPは以前「Preview」状態で、利用するにはドキュメントからアクセスリクエストを送る必要がありました。ずっと申請していたのですが、2026年3月9日にGA(一般提供)が発表され、誰でも利用できるようになりました。GAになったばかりのタイミングで使い始めたのですが、これが本当に調査を劇的に改善しました。

コドモンではほとんどのログをDatadogに集約しているため、調査の過程で必ずDatadogを見に行く必要があります。 今まではDatadogのUIを開いて、関連するログを手動で検索して、トレースを辿って……という一連の作業が必要でした。それがMCPを通じてClaudeから直接Datadogのログ検索、トレース取得、モニター確認、サービス依存関係の把握ができるようになりました。最後のワンマイルがつながった、という感覚です。

Skillsの中で利用しているDatadog MCPのツールは主に以下のものです。

ツール 用途
search_datadog_logs エラーログの検索
analyze_datadog_logs ログパターンの分析
get_datadog_trace トレースの詳細取得
search_datadog_spans スパンの検索
search_datadog_monitors モニターの状態確認
search_datadog_services サービスの依存関係把握

これらを組み合わせることで、「ログでエラーを発見 → トレースで処理の流れを追う → モニターで影響範囲を確認」という人間がやっていた調査フローをそのまま自動化できています。

MCPである必要はあるのか?

DatadogだけMCPを使っているのは、Datadogのリソースにプログラマティックにアクセスする方法として、現状MCPが最も手軽だからです。

ただし、全てをMCPにする必要はないと考えています。こちらの記事でも述べられているように、MCPはコンテキストの消費が大きく、CLIで十分な場合はCLIのほうが効率的です。推論モデルの進化により、manページやヘルプテキストから適切なコマンドを自動的に構築できるようになった今、MCPの優位性は限定的になりつつあります。

AWS CLIやgcloudコマンドは、まさにCLIで十分なケースです。MCPを使う場合、SSOを用いた認証の設定が煩雑になりがちですが、CLIなら認証できなかったときにユーザーに aws sso login を促すだけで済みます。とてもシンプルです。

Skillsの中でも、認証に失敗した場合は以下のように案内するよう定義しています。

aws sso login --profile <name>

あらかじめSSOで認証しておけば、あとは全てClaudeが自動で調査を進めてくれます。profileを指定すれば後続のコマンドでは一貫してそのprofileを使って実行してくれます。

さらに、CLIベースのアプローチには「AIにコマンドを生成させて、自分で実行する」という選択肢もあります。MCPはツール呼び出しが自動で実行されますが、CLIならAIが組み立てたコマンドを確認してから手動で実行することもできます。特に本番環境への操作など慎重さが求められる場面では、この「コマンドだけ作ってもらう」使い方が安心感につながります。

GitHub操作もターミナルから完結する

調査だけでなく、日常的なGitHub操作もターミナルから離れずに完結します。gh コマンド(GitHub CLI)を使えば、Issue やPR の確認・作成・レビューまで全てClaude Codeの中で行えます。

# PRの一覧確認
gh pr list

# 特定のIssueの詳細を確認
gh issue view 123

# CIの実行状況を確認
gh run list

これらのコマンドはClaude Codeが自動的に実行してくれるので、自分でコマンドを覚える必要はありません。「このPRのレビューコメントを確認して」「最新のCIの状況を教えて」と言えば、適切な gh コマンドを組み立てて実行してくれます。

ワークフロー失敗の調査も一気通貫

特に便利なのが、CI/CDワークフローの失敗調査です。Slackに来たワークフロー失敗の通知をそのまま貼り付けて、

失敗したワークフローの原因を調べて

と指示するだけで、Claudeは gh run view でワークフローのログを取得し、失敗したステップを特定し、さらに必要に応じてAWS CLIでデプロイ先のリソース状態を確認し、原因の特定からコードの修正提案までを行ってくれます。

以前であれば、GitHubのActions画面を開いてログを読み、AWSコンソールに移動してリソースの状態を確認し、またエディタに戻ってコードを修正する——という複数のツールを行き来する作業が必要でした。それが今はターミナル一つで完結します。

権限の安全性について

「CLIで何でも実行できてしまうのは危険では?」と思うかもしれません。

基本的にはAWSアカウントレベルで実行可能な操作が制限されているため、それほど神経質になる必要はありません。SSOで割り当てられた権限セットの範囲内でしか操作できないので、誤って本番環境のリソースを変更してしまうようなリスクは低いです。

とはいえ、更新系のコマンドについては注意を払っています。Claude Code自体も、破壊的な操作を行う前にはユーザーに確認を求める仕組みになっているので、二重の安全策があると言えます。

課題:コンテキストを与えることの難しさ

一方で、まだ解決できていない課題もあります。コンテキストを与えることの難しさです。

インフラの構成やログの設計には、設定した人の意図があります。「なぜこのキューのvisibilityTimeoutは300秒なのか」「なぜDLQのmaxReceiveCountは3なのか」「なぜこのモニターの閾値はこの値なのか」といったコンテキストは、コード内にコメントがなければ、ADRなどのドキュメントを探すしかありません。

現状、私たちのチームではドキュメントをGoogle Docsに集約していますが、その情報はMCPやAPIでは取得しづらい状態です。もしこのコンテキスト情報をClaudeに渡すことができれば、本当にチームの一員のように動いてくれるだろうと期待しています。

今はまだ、「外部に調査を依頼している」ようなイメージです。調査の手順と実行をこなしてくれますが、「なぜそうなっているのか」という背景知識については人間が補完する必要があります。ドキュメントのMCP対応や、CLAUDE.mdへのコンテキスト追記など、この辺りは今後改善していきたいポイントです。

まとめ

Slackに来たアラートから、Claude Codeを活用して読み解くだけで調査が完了する。これが今の私たちの開発体験です。

構成要素を整理すると、以下の通りです。

要素 役割 接続方法
Datadog ログ・トレース・モニター・メトリクス MCP
AWS インフラリソース・CloudWatch CLI(SSO認証)
GitHub Issue・PR・ワークフロー管理 CLI(gh コマンド)
コードアクセス 複数リポジトリの横断 ~/Dev で実行 or gh コマンド
Skills 調査手順の定義・ドメイン知識 ~/.claude/skills/(グローバル)
.claude/skills/(プロジェクト)

全てをMCPにする必要はありません。CLIで十分なものはCLIで、MCPでしかアクセスできないものだけMCPで。この使い分けがシンプルで実用的です。

コンテキストの問題が解決されれば、調査だけでなく、障害対応そのものをAIがエンジニアのパートナーとして並走する世界もそう遠くないと感じています。