📌

インフラのモニタリングをAIと伴走する

に公開

見きれないDatadogのモニタリングをDevinに任せて、毎朝Slackにレポートしてもらう

株式会社GENDAのエンジニアのジャンボです。

新しく事業に参画して、まるっとシステムを見ることになったとき、インフラやモニタリングしているメトリクスに関心を持ちたいのに、なかなか時間が取れないことってありますよね。今関わっているプロダクトではDatadogを使っていて、さまざまなメトリクスを可視化したり、できる限りのAlert/Monitorの設定もしているんですが、より理解を深めリスクに備えるためにAI(Devin)を使うことにしました。

定期的にAI(今回はDevin)にDatadogの情報を収集・分析してもらい、Slackにレポートとして投稿する運用をしており、本記事ではそれを紹介します。

ざっくりとした仕組みとしては以下の通り。下部に詳細を述べます。

Devin Automations(毎朝定時)
  → リポジトリを取得
  → /datadog-monitoring スキルを実行(Datadog MCP で APM・メトリクスを取得)
  → markdown レポートを生成
  → Slack に投稿

なぜDevinか

実現できる手段は多くあると思います。今回Devinにした理由は3つあります。

  1. 定期実行したい
  2. 実行するスキル(プロンプト+手順書)はGitHubで管理したい(定期実行するだけでなく、障害時や特定のタイミングでローカルでも実行したい)
  3. 投稿されたレポートに対して、Slack上で追加調査を依頼したり、修正を指示したりしたい

DevinはAutomationsの機能を持っていて、リポジトリのコードやスキルを参照して実行でき、投稿後もSlackで会話を続けられるので、この3つをまとめて満たせると考えて選択しました。

やってみて

これまでふんわり理解していたエラーの傾向や費用の傾向が数字でわかるようになり、インフラリソースやアプリケーションの使われ方の解像度が上がりました。毎朝レポートがSlackに流れてくるので、リリースやインフラ変更の影響が出ていないかを自分だけでなくチーム全体で簡単に共有・把握できるようになりました。

また、利用者が今後増えていった場合のボトルネックやインフラコストについての勘所もつかめて、中・長期的なロードマップを作りやすくなりました。

やったこと

Devin側の設定

Devin側はAutomationの設定をして、実行時刻とプロンプトを指定するだけです。

{リポジトリ名} を取得し、/datadog-monitoring daily のスキルを実行し結果を {チャンネル名} に通知してください

これだけで毎朝、Devinがリポジトリを取得してスキルを読み込み、Datadogを見に行って、結果をSlackに投稿してくれます。

実際にはこんな投稿が毎朝届きます(固有名・件数・金額はマスクしています)。詳細なmarkdownレポートはリポジトリに保存され、Slackにはそのサマリと、実行したDevinセッションへのリンクが付きます。気になる点があればこの投稿のスレッドでそのまま追加調査を頼めます。

xxx Datadog daily モニタリング(対象: 2026-08-18 UTC日)要確認 1件: xxx テーブルの重複キーエラー(xxx_unique_key / UPDATE xxx SET ... WHERE ...)が 08-17 NN件 / 08-18 NN件 と直近2日で増加(08-09〜08-16 は 一桁〜十数件)。API 全体のエラー率は低下しており影響は限定的だが、増加理由は Datadog だけでは未特定(件数は span ベースのため参考値)。

  1. リクエスト N,NNN,NNN件(NN.N req/s) / BL日次平均 N,NNN,NNN → -13.7%(前週火曜比 -19.9%)。ただし平日は一定レンジ内で対象日はその範囲内、BL 期間(08-11〜08-16)が休暇期で高め。上位リソースは一律 -19〜-24% で欠落・新規なし。
  2. エラー NNN件・0.0231%(BL NNN件・0.0310%)、5xx NNN件 -37.3%、4xx率 4.48%(BL 4.45%)。DB エラー NN件(BL NN件/日)。
  3. パフォーマンス p50 0.0166s / p95 0.275s(BL 0.272s, +0.8%)/ p99 0.577s(BL 0.634s)。xxx.query p95 2.07ms(BL 2.15ms)。遅いリソースの悪化なし(+側の2リソースは 十数〜千件/日で標本過小)。
  4. AWS コスト 対象日 08-18 は 00:00Z 累積スナップショット未着で 未取得。直近確定日 08-17 = $NNN(BL前7日平均 $NNN、+3.4%)。変動サービスは xxx -$2.16(-24.1%)のみ・要確認なし。

継続観測中の xxx 機能の 500 エラー率: 08-14 1.124% → 08-18 0.583% と低下継続、従来水準を下回り収束。レポート: projects/monitoring/daily-2026-08-19.md | BL: 08-11〜08-17(UTC日, 日次平均) | Devin session

「要確認が先頭に来る」「すべてベースライン(BL)との増減で書かれる」「取れなかったものは未取得と明記される」あたりが、スキルの大原則がそのまま出力に効いている部分です。

Skill

スキルは2ファイル構成にしています。

  • SKILL.md: 何を・どういう手順と原則でやるか(振る舞いの定義)
  • reference.md: 監視対象のサービス名・時間窓・クエリの注意点など、定数とノウハウ集

DatadogへのアクセスはDatadog MCP経由です。以下、サービス固有なところは xxx にリプレースしたり割愛したりしていますが、だいたいこういう内容を定期実行しています。

まずSKILL.mdです。

---
name: datadog-monitoring
description: Datadog の APM とコストメトリクス(AWS 利用金額)を参照して xxx の API・DB・AWS費用を運用モニタリングし、問題を事実ベースで洗い出して markdown レポートにまとめる。毎日朝の定期チェック(直近1日 vs 直近数日)、毎週月曜の週次チェック(先週 vs 先々週)、リリース後チェック、障害発生時の調査・状況整理に使用。
---

あなたは xxx の Web サービス運用モニタリング担当です。Datadog の **APM**(API・DB)と
**コストメトリクス**(AWS 利用金額)を参照して状態を確認し、**問題を事実ベースで洗い出して**
簡潔な markdown レポートにまとめます。これは監視・調査専用で、Datadog の設定や monitor は変更しません。

**まず同ディレクトリの reference.md を必ず読み込んでください。**
監視対象サービス名・時間窓・確認項目の指標・レポートテンプレートなどの定数はそこにあります。

# 大原則(厳守)

- **憶測を入れず事実ベースで書く**: レポートの各項目に**根拠**(何を・どの期間で見たか、実際の数値)を添える。
  観測事実と、そこからの推測を混ぜない。原因は断定しない。
- **「確実 / 要確認 / 未取得」を区別する**: Datadog で確認できた事実は「確実」、値が異常だが原因が特定
  できないものは「要確認」、データが取得できなかった項目は「未取得」と明記する。**根拠のないことは創作しない**
- **比較で語る**: 「多い/遅い」ではなく、必ずベースライン期間と比べた**増減(数値・割合)**で示す。
- **Datadog へは MCP でアクセスする**
- **読み取り専用**: monitor / dashboard / SLO の作成・編集・削除はしない。
- **タイムゾーン**: 時間窓・レポートの時刻は **JST** で扱い、レポートに `JST` と明記する。
- **レポートは簡潔に**: 表・箇条書き中心。

# モード

引数でモードを指定する。引数がなければユーザーに確認する。

| モード | 用途 | 実行タイミング |
|---|---|---|
| `daily` | 直近1日を直近数日と比較 | 毎日朝 |
| `weekly` | 先週を先々週と比較 | 毎週月曜 朝 |
| `post-release` | リリース前後を比較 + 直近数日ベースライン | リリース後 |
| `incident` | 障害の発生時刻周辺を調査・状況整理 | 障害発生時 |

# 進め方

最初に下記ステップをタスク登録してから着手する。

## ステップ0: 前提確認

1. reference.md を読み込む。
2. Datadog MCP が利用可能か確認する。
3. **監視対象サービス名の確認**: reference.md 記載の APM サービス名・DB span が Datadog 上に
   実在するか確認する。表記が異なれば実名を特定し、reference.md に追記して以降再利用する。
4. モードを確定する(引数がなければ確認)。

## ステップ1: 時間窓の確定

reference.md の「モード別 時間窓」に従い、対象期間とベースライン期間を確定する(すべて JST)。
- `post-release`: リリース時刻を確認する。既定は前後 2 時間、必要に応じて調整。
- `incident`: **発生時刻帯と症状を対話で受け取り**、その窓を確定する。

## ステップ2: 共通確認項目の収集(4軸)

対象期間について、軸1〜3は API(`xxx-api`)と DB(`xxx.query`)を対象に Datadog APM で、
軸4(AWS コスト)はコストメトリクスで収集する。取得できない項目は「未取得」として記録する。

1. **APIリクエスト傾向**: リクエスト数(hits)、エンドポイント(リソース)別の内訳・上位。
2. **エラーの発生傾向**: エラー率・エラー数、HTTP ステータス別、エラーの多いリソース、DB のエラー。
3. **パフォーマンス**: レイテンシ p50 / p95 / p99、遅いリソース上位、DB のクエリレイテンシ。
4. **AWS コスト**: メトリクス `aws.billing.estimated_charges``servicename` 別)で、AWS サービス別の
   利用金額(上位と合計)と、ベースライン(前7日の日次平均)との増減を収集する。
   **この指標は月内累積・月初リセット**のため、日次コスト=前日との差分で算出する
   (詳細は reference.md「AWS コスト」参照)。

## ステップ3: ベースラインとの比較

同じ4軸をベースライン期間についても収集し、**対象期間との差分(増減の数値・割合)**を算出する。
`incident` では発生前・平常時との差、および時系列の変化を捉える。

## ステップ4: レポート作成

reference.md の「レポートテンプレート」に従い、markdown を作成して保存する。

- 冒頭に対象期間・ベースライン期間・実行時刻(JST)・確認したサービス名を明記する。
- 各軸ごとに「確実 / 要確認 / 未取得」を区別して記載する。

# 終了時

- レポートの保存パスと、**要確認事項(あれば)**を簡潔に報告する。
  要確認が無ければ「事実として観測された異常なし」と述べる。
- 今回判明した未登録の定数(実サービス名・リソース名など)があれば reference.md に追記する。

次にreference.mdです。定数のほか、運用しながらハマったポイント(AWSの課金メトリクスが月内累積だった、spanのdurationはナノ秒だった、など)をここに追記して育てています。

# 監視対象(Datadog APM)

| 対象 | 種別 | 実名(確認済み) | クエリ例 |
|---|---|---|---|
| API サービス | APM service | `xxx-api` | `service:xxx-api` |
| API リクエスト入口 | span operation | `http.request` | `service:xxx-api operation_name:http.request` |
| DB クエリ | span operation | `xxx.query`(※ 当初想定した span 名では存在しなかった) | `service:xxx-api operation_name:xxx.query` |
| 環境 | tag | `env:production` | `service:xxx-api env:production` |

- Datadog 上の実サービス名・span 名は運用で変わり得る。**スキルのステップ0 で必ず実在を確認し、
  異なれば実名をここに追記する。**
- `duration` の集計フィールドは `@duration`(ナノ秒)。percentile は P50/P95/P99 を使う。

# モード別 時間窓(すべて JST)

| モード | 対象期間 | ベースライン期間 |
|---|---|---|
| `daily` | 実行時刻までの直近 24 時間 | 直近 7 日(対象期間を除く。日次平均と比較) |
| `weekly` | 先週(月曜 00:00 〜 日曜 24:00) | 先々週 |
| `post-release` | リリース時刻の前後(既定 各 2 時間) | 直近 7 日(平常時) |
| `incident` | 発生時刻帯を中心とした窓(対話で確定) | 発生直前 / 直近数日の平常時 |

- `post-release` のリリース時刻は、GitHub のデプロイ Actions 完了時刻(`gh run list ...`)、
  または Datadog の deployment マーカーから特定する。不明ならユーザーに確認する。
- リリース直後だと後続データが乏しい(数分では標本過小)。リリース完了から2時間程度経過後の実行が望ましい。

## 現在時刻の確定(重要)

- 実行環境のローカル時刻が実時刻とずれる場合があるため、時間窓の起点は **Datadog 側の実時刻に合わせる**
  (直近の集計バケットの timestamp で現在時刻を把握する)。
- Datadog クエリに絶対時刻を渡すときは ISO 8601 + オフセットで曖昧さを排す(例: `2026-06-22T00:00:00+09:00`)。
- 日次推移の histogram バケットは Datadog 仕様で **UTC 日境界**(00:00Z = 09:00 JST)区切りになる。
  JST の日と1:1対応しないため、レポートで明示する。

# 共通確認項目(4軸)と収集する指標

(1〜3 は割愛。リクエスト数・エラー率とステータス別内訳・p50/p95/p99 と遅い resource 上位を、
対象期間 ↔ ベースライン期間の増減つきで収集する)

## 4. AWS コスト(AWS サービス別利用金額)
- メトリクス: `aws.billing.estimated_charges`(gauge・USD)。`servicename` タグでサービス別に分解。
- **重要(月内累積・月初リセット)**: この指標は「その月の月初からの累積額」で、毎月1日に 0 付近へ
  リセットされる。したがって **日次コストは前日との差分**で求める:
  - 月初でない日 d: `日次コスト(d) = 値(d) − 値(d−1)`
  - 月初(1日): `日次コスト = 値(1日)`
  - **前日差分をとる際に月境界(30/31日→1日)をまたぐ計算をしない**(負値になる)。
- **表示ルール(動きのあったもののみ)**: コスト表には**変動のあったサービスだけ**を載せる。
  ベースラインとほぼ差がない(`|増減率| < 10%` かつ `|増減額| < $2`)サービスは行に出さず、
  「ほぼ変動なし: N件」と件数だけ添える。**合計行は常に表示**する。
- **要確認の目安**: 前7日日次平均比 +20% 以上、かつ金額インパクトがある場合は「要確認」として明記する。
  率だけ大きくても金額が僅少なものは「金額僅少」と付記する。

# 事実ベース記述のルール

- 各項目に**根拠**を必ず添える: 「何を(指標)・どの期間・どのサービス/リソースで・実測値いくつ」。
- **確実**: Datadog で数値として確認できた事実。
- **要確認**: 値が異常・急変しているが原因が Datadog だけでは特定できないもの(該当 trace / log への
  ポインタを添える)。
- **未取得**: データが取得できなかった / 該当データが存在しなかった項目(「なし」と「未取得」を区別する)。
- 原因の断定・対応策の提案はしない(観測事実と、時系列の変化の記述にとどめる)。

# レポートテンプレート

## daily / weekly / post-release 用

```markdown
# モニタリングレポート({mode})

- 実行時刻: {YYYY-MM-DD HH:MM} JST
- 対象期間: {期間} JST
- ベースライン期間: {期間} JST
- 対象サービス: {確認したサービス名}
- env: prod

## サマリ
- 要確認事項: {件数}(無ければ「観測された異常なし」)
- {1〜3行で全体所感を事実ベースで}

## 1. API リクエスト傾向
| 指標 | 対象期間 | ベースライン | 増減 | 区分 |
|---|---|---|---|---|
| 総リクエスト数 | | | | 確実 |
| 上位リソース… | | | | 確実 |

## 2. エラーの発生傾向
| 指標 | 対象期間 | ベースライン | 増減 | 区分 |
|---|---|---|---|---|
| エラー率 | | | | |
| 5xx 数 | | | | |
| DB エラー | | | | |
- 主なエラー: {resource / message / trace ポインタ}

## 3. パフォーマンス
| 指標 | 対象期間 | ベースライン | 増減 | 区分 |
|---|---|---|---|---|
| p95 レイテンシ | | | | |
| p99 レイテンシ | | | | |
| DB クエリ p95 | | | | |
- 遅いリソース: {resource と実測値}

## 4. AWS コスト(サービス別利用金額)
| AWS サービス | 対象日(USD) | 前7日日次平均(USD) | 増減額 | 増減率 | 区分 |
|---|---|---|---|---|---|
| {変動のあったサービスのみ} | | | | | |
| **合計** | | | | | 確実 |
- 要確認: {サービスと増減。無ければ「なし」}

## 未取得項目
- {取得できなかった項目。無ければ「なし」}
```

(incident 用テンプレートは割愛。時系列の観測事実表+3軸の変化+要確認事項、という構成)

# MCP クエリの注意(運用で確認した知見を追記していく)

- **span(トレース)ベースのエラー件数は保持(retention)設定の影響を受ける**。retention の変更を
  またぐ期間比較はしない。**件数のトレンドは必ずメトリクス
  `trace.http.request.hits` / `trace.http.request.errors``.as_count()`)で見る**。
  span は直近のエラー内容・メッセージの深掘り用。
- percentile / AVG の集計 field には **`@duration`** を指定する(`duration` では値が返らない)。単位はナノ秒。
- **7日などの長期間で group_by(status_code 等)を伴う集計はタイムアウトしやすい**。その場合は
  範囲クエリで分割する(例: `@http.status_code:[500 TO 599]` の COUNT)。
- エラー span の issue 系タグ(初出日時・初出バージョン)で**既知エラーか新規か**を判別できる
  (post-release で新規エラーパターン検出に有効)。
- 既知の常在エラーはここに列挙しておく(毎回「要確認」に上がってこないようにする)。

スキル設計で意識したポイント

  • 憶測禁止・事実ベースの強制。AIにレポートを書かせると、放っておくと"それっぽい推測"を混ぜてきます。「確実 / 要確認 / 未取得」の3区分を強制し、各項目に根拠(指標・期間・実測値)を添えさせることで、レポートを信頼して読めるようにしています。
  • 比較させる。「エラーが多い」ではなく「ベースライン比 +N%」。単発の数値はAIも人間も評価できないので、必ずベースライン期間との増減で書かせます。
  • ハマりどころをreference.mdに記載aws.billing.estimated_charges が月内累積で月初にリセットされる、spanのdurationはナノ秒、長期間のgroup_by集計はタイムアウトする——一度ハマった知見を追記しておくことで、毎回同じ品質のレポートが出てきます。
  • スキル自身にreference.mdを更新させる。ステップ0で監視対象の実名を確認して違えば追記、終了時に判明した定数を追記、というループを仕込んであるので、運用するほどスキルが賢くなっていきます。

まとめ

毎朝のDatadogチェックをDevin+スキルに任せたことで、「頑張らなくてもシステムの解像度が上がっていく」状態を作れました。

ポイントは、AIへの指示(スキル)をGitHubで管理していることだと思っています。レポートの内容に不満があればPRで直せばいいし、障害時には同じスキルを incident モードでローカルから実行できます。運用で得た知見(実サービス名、メトリクスの罠、既知の常在エラー)はreference.mdに蓄積されていくので、続けるほどレポートの質が上がっていきます。定期実行の仕組み自体はDevinのAutomationにプロンプトを1行書くだけなので、導入コストもほぼありません。

と、ここまで書いておいてなんですが、最近はSREチームと連携してDevOps Agentを使っても同様のことできないかというのでやってみています。今のところだいぶいいレポートが作れているので乗り換えようとも考えていますが様子見中・・・

GENDA

Discussion