- 1 §1 なぜ Observability Vol3 か — 50記事化大台達成 + SLO思考法 + 三部作ナビ
- 2 §2 Application Signals 本番運用 — SLO自動定義 × Service map auto-discovery × Latency/Availability × Burn rate ★山場1
- 3 §3 SLO/SLI 管理本番運用 — SLI設計 × Error budget × Multi-window multi-burn-rate × 段階エスカレーション
- 4 §4 Service Map 本番運用 — 依存関係可視化 × Top contributor × Cross-account × Hybrid environment
- 5 §5 CodeGuru Profiler 本番運用 — Continuous Profiling × Hot path特定 × Cost optimization × Heap summary ★山場2
- 6 §6 詰まりポイント7選 図解 (Mermaid01 判断ツリー)
- 6.1 詰まり1: SLO目標値を高く設定しすぎてError budgetが枯渇
- 6.2 詰まり2: Burn rate windowを短期のみ設定してアラート疲労が発生
- 6.3 詰まり3: Service Map ノイズで依存関係が見えにくい
- 6.4 詰まり4: CodeGuru Profiler Agentの本番オーバーヘッドが予想を超えた
- 6.5 詰まり5: Multi-account Service Map でクロスアカウント集約に失敗
- 6.6 詰まり6: デプロイ直後のウォームアップ期間でProfile diffが誤判定
- 6.7 詰まり7: Continuous Profiling の料金計算でコストが大幅超過
- 7 §7 アンチパターン → 正解パターン変換演習 (5問)
- 8 §8 まとめ + Observability三部作完成 + 50記事化大台達成 + 全軸クロスリンクナビ
§1 なぜ Observability Vol3 か — 50記事化大台達成 + SLO思考法 + 三部作ナビ
本記事が解くシナリオ
あなたのチームは X-Ray によるトレース収集を整備し、CloudWatch Logs Insights でのログ分析も運用に乗っている。しかし依然として次の問いに明確に答えられない状態にあるとしたら、本記事はそのギャップを埋めるために書かれている。
- 「今の本番は SLO を達成しているか?」 — ダッシュボードの数字は見えているが、それが目標値に対して “今月何%消費しているか” まで即座に答えられない
- 「障害の影響範囲はどのサービスか?」 — X-Ray トレースは取れているが、複数マイクロサービスが連鎖する中でどこが Root cause かを Service Map なしで追うのに時間がかかる
- 「本番アプリの CPU/メモリボトルネックはどこか?」 — プロファイリングを試みるが定期的な Continuous Profiling ができておらず、Hot path の変化を継続監視できていない
これらは「トレースとログがある」という状態から「SLO で守られた本番を運用する」状態への移行に必要なピースだ。AWS Application Signals × SLO/SLI × Service Map × CodeGuru Profiler はその移行を AWS マネージドサービスで実現する。
AWS 本番運用の監視設計は「ダッシュボードを作れば終わり」という時代から大きく進化した。トレースを収集し、ログを集約しても、「何を守るべきか」の定義がなければ、アラートは鳴り止まないか、あるいは本当に重要な障害を見逃す。本記事はその問いに正面から答えるための Observability 本番運用 Vol3 だ。
AWS Observability 本番運用シリーズ — 三部作の構成
本シリーズは、AWS 上の Observability 基盤を段階的に構築するための三部作として設計している。
Vol1 — 基礎運用編 (X-Ray / OTel / Application Signals / ADOT)
X-Ray によるトレース収集と分散トレーシングの基礎、OpenTelemetry (OTel) による計装の標準化、Application Signals の初期セットアップ、ADOT (AWS Distro for OpenTelemetry) Collector の構築を扱う。「何が起きているか」を可視化するための土台を築く巻。
Vol1 で特に重点的に扱ったのは次の 3 点だ。① X-Ray Daemon / ADOT Collector の ECS・EKS・Lambda 別展開パターンと、それぞれのトレースサンプリング戦略。② OTel SDK (Java / Python / Node.js) による自動計装と手動スパン追加の使い分け。③ Application Signals の初期有効化と CloudWatch コンソールでの Service Map (基礎) 確認手順。
Vol2 — Logs 縦深化編 (CloudWatch Logs Insights / Lambda統合 / Centralized / コスト最適化)
CloudWatch Logs Insights による高速ログ分析クエリ、Lambda との統合 (Log Groups 設計 / Structured Logging)、Centralized Logging 基盤の構築 (Kinesis Firehose / OpenSearch / S3)、コスト最適化 (S3 Intelligent-Tiering / Glacier) まで踏み込んだ。「なぜ起きたか」をログで追跡するための縦深化巻。
Vol2 では特に次の 3 点を重点化した。① Logs Insights のパターンマッチクエリと stats コマンドによる集計クエリの実践例。② Lambda の非同期呼び出し (SQS / SNS トリガー) でログが分断される問題と Structured Logging による相関 ID 設計。③ S3 エクスポートによるコスト削減 (Glacier Instant Retrieval 移行) と Retention Policy の適切な設計。
Vol3 — SLO/Profile 層 完結編 (本記事)
Application Signals 本格運用 (SLO 自動定義 / Service Map auto-discovery / Burn rate)、SLO/SLI 管理 (Error budget / Multi-window multi-burn-rate)、Service Map 本番運用 (Top contributor / Cross-account / Hybrid)、CodeGuru Profiler による Continuous Profiling (Hot path / Cost optimization / Heap summary) を扱う。「何を守り、どこがボトルネックか」を定義・自動管理する上位層の巻。
Vol3 が扱う Observability 上位層は、Vol1/Vol2 の「収集・格納・検索」基盤の上に乗る「目標定義と自動管理」レイヤーだ。SRE の黄金律「Toil を減らし、エンジニアリングに集中する」を Observability に適用するとき、Application Signals の SLO 自動定義と Burn rate アラートはその核心となる。
50記事化大台達成 — AWS本番運用シリーズの節目
本 Vol3 の公開をもって、AWS 本番運用シリーズが 50 記事の大台を達成した。
Container (ECS/EKS)、Serverless (Lambda/API GW)、Database (Aurora/DynamoDB/ElastiCache/Aurora DSQL)、Security、AI/ML (Bedrock/SageMaker)、Network/Edge、DevOps CI/CD、IoT Vol1+Vol2、Game/Media Vol1 と主要 AWS サービス軸を横断しながら積み上げてきたシリーズが、Observability 三部作の完結をもって 50 本に到達した。
50 記事という節目は単なる数字ではない。各軸を縦深化し、Vol1→Vol2→Vol3 と体系的に積み上げた知識が相互に参照できる状態を達成したことを意味する。本記事 §8 では全 20+ 軸のクロスリンクをまとめ、次の縦深化サイクルへの道標を示す。
各軸の現状 (50記事時点):
| 軸 | 現行巻数 | 主要トピック |
|---|---|---|
| Observability | Vol1〜Vol3 (完結) | X-Ray / OTel / App Signals / Logs / SLO / CodeGuru |
| Container | Vol1〜Vol3 | ECS / EKS / Fargate / Pod Identity / Karpenter |
| Serverless | Vol1〜Vol2 | Lambda / API GW / EventBridge / Step Functions |
| Database | Vol1〜Vol4 | Aurora / DynamoDB / ElastiCache / Aurora DSQL |
| AI/ML | Vol1〜Vol3 | Bedrock / SageMaker / MLOps Pipelines / Feature Store |
| DevOps CI/CD | Vol1〜Vol3 | CodePipeline / CDK Pipelines / GitOps / ECS Blue/Green |
| Network / Edge | Vol1〜Vol2 + Hybrid | CloudFront / WAF / PrivateLink / Transit GW |
| IoT | Vol1〜Vol2 | IoT Core / Greengrass / SiteWise / IoT Events |
| Security | Vol1〜Vol3 | IAM / KMS / Macie / Config / Detective |
| Game/Media | Vol1 | CloudFront + MediaConvert / IVS / AppStream 2.0 |
この網羅性が、単一サービスの HowTo 記事では得られない「設計判断の文脈」を提供する。例えば「EKS クラスタの可観測性設計」を考えるとき、Container Vol3 の Pod Identity + Karpenter、Observability Vol3 の Service Map + SLO、DevOps Vol3 の CDK Pipelines が連携する全体像を、シリーズを横断して参照できる状態が完成した。
SLO思考法の転換 — “Uptime %” から “Error budget + Burn rate” へ
多くのチームが最初に選ぶ監視アラートは「可用性 99.9% を下回ったら通知」というアップタイムベースの閾値だ。しかしこのアプローチには根本的な問題がある。
アップタイム % が抱える限界:
- 粒度の粗さ — 月次 99.9% は 43.2 分の障害を許容する。しかしその 43.2 分がピーク時に集中するか深夜に集中するかは区別されない。同じ SLO 達成でもユーザー影響は全く異なる
- 遅延検知 — 月次集計では障害進行中に気づけない。リアルタイムの Burn rate がわからないと対応が後手に回り、手遅れになってから通知が届く
- バジェット感覚の欠如 — 今月あと何分の障害を許せるかという “残高” の概念がなく、リリース可否判断やインシデントの定量評価に使えない
SRE の標準的な解答が SLO + Error budget + Burn rate の組み合わせだ。
| 概念 | 定義 | 実用例 |
|---|---|---|
| SLI (Service Level Indicator) | 測定する指標 | HTTP 2xx 比率 / p99 レイテンシ |
| SLO (Service Level Objective) | SLI の目標値 | 可用性 99.9% / p99 < 300 ms |
| Error budget | SLO から逆算した “許容障害量” | 月 43.2 分 / リクエスト 0.1% |
| Burn rate | Error budget の消費速度 (倍率) | 1.0 = ちょうど SLO 境界 / 14.4 = 1h で月次を食い尽くすペース |
Burn rate が 1.0 であれば「ちょうど SLO 境界ペース」、14.4 であれば「このペースが 1 時間続くと月次バジェットを使い切る」という直感的な指標になる。AWS Application Signals はこの SLO + Burn rate の設計を CloudWatch に統合し、SLO の自動定義・Service Map の自動検出・Burn rate アラートの自動設定を提供する。本記事ではその本番運用パターンを体系化する。
具体的シナリオ: Burn rate アラートが on-call 運用を変える
例として、ECサイトの注文 API が 99.9% 可用性 SLO を持つとする。月次 Error budget は 43.2 分。ある日の午前 10 時に HTTP 503 エラーが散発し始めたとき、従来の「99.9% 閾値アラート」では月末集計まで気づかない可能性がある。
Burn rate アラートでは異なる結果になる。10 時の時点で Burn rate が 14.4 倍に達すると、Short window (5 分) と Long window (1 時間) の両方が閾値超過し、P1 (Critical) アラートが即座に発報される。これは「このまま放置すると今日中に月次バジェットを使い切る」というシグナルだ。on-call エンジニアは「月末に SLO 未達になるかも」ではなく、今すぐ対応しなければならない理由 を数値で確認して行動できる。
Error budget の残量が可視化されることで、リリース判断にも変化が生じる。「Error budget が 50% 以上残っている週はリリース可」「20% を下回ったらフリーズ」という運用ルールは、定性的な「品質が高い/低い」の議論を数値に置き換える。Application Signals はこの一連の設計を AWS マネージドサービスとして提供し、独自 SLO 計算基盤の構築コストを大幅に削減する。
本記事で得られる実践的知識
| テーマ | 得られるスキル |
|---|---|
| Application Signals 本番運用 | SLO 自動定義 / Service map auto-discovery / Latency・Availability SLO / Burn rate alert 設計 |
| SLO/SLI 管理 | SLI 設計 4 本柱 / Error budget 月次運用 / Multi-window multi-burn-rate 段階アラート |
| Service Map 本番運用 | 依存関係可視化 / Top contributor 特定 / Cross-account 統合 / Hybrid 環境対応 |
| CodeGuru Profiler | Continuous Profiling / Hot path (Flame Graph) / Cost optimization / Heap summary |
| 詰まりポイント 7 選 | SLO 定義罠 / Burn rate window 設計 / Service Map noise / CodeGuru overhead 他 |
| アンチパターン演習 5 問 | 手動 Dashboard → App Signals / Uptime % → SLO / CPU 単発 → Continuous Profiling 他 |
対象読者
本記事が最も役に立つのは以下のような読者だ。
- SRE エンジニア / Platform engineer として本番 SLO 管理を担っており、CloudWatch アラートの誤報・見逃しに悩んでいる
- Application Signals を試験導入 (Vol1 相当) したが、本格 SLO 運用 (Burn rate アラート / Service Map 本番展開) に踏み込めていない
- マイクロサービス間の依存関係を可視化し、障害時の Root cause 特定速度を上げたい
- Java / Python アプリのパフォーマンスボトルネックを Continuous Profiling で継続的に監視したい
- Error budget の概念は理解しているが、AWS での具体的な実装パターン (Terraform / CDK) がわからない
Vol1/Vol2 を読了していることが望ましいが、本 Vol3 は各章の冒頭に前提知識を簡潔にまとめているため、Vol3 単体でも読み進められる構成にしてある。
本記事の構成
本記事は 8 章で構成される。§1 (本章) でシリーズ全体と SLO 思考法の概要を掴んだ後、§2〜§5 で 4 つの主要テーマを深掘りし、§6〜§7 で実践力を養い、§8 でシリーズ完結とクロスリンクナビに戻る構成だ。
| 章 | テーマ | ポイント |
|---|---|---|
| §1 | イントロ + SLO 思考法 + 三部作ナビ (本章) | Observability 三部作の全体像と SLO 思考法への転換 |
| §2 | Application Signals 本番運用 ★山場1 | SLO 自動定義 / Service map auto-discovery / Burn rate |
| §3 | SLO/SLI 管理本番運用 | SLI 設計 4 本柱 / Error budget / Multi-window アラート |
| §4 | Service Map 本番運用 | 依存関係可視化 / Top contributor / Cross-account / Hybrid |
| §5 | CodeGuru Profiler 本番運用 ★山場2 | Continuous Profiling / Hot path / Cost optimization |
| §6 | 詰まりポイント 7 選 | SLO 定義罠 / Burn rate window / overhead 等 7 パターン |
| §7 | アンチパターン → 正解パターン演習 5 問 | 変換演習で本番設計力を身につける |
| §8 | まとめ + 三部作完成 + 50 記事化告知 + 全軸ナビ | 50 記事化大台達成の総括と全軸クロスリンク |
§2 と §5 が「山場」の章であり、Terraform / CDK の完全なコード例と ep-box による鉄則・チェックリストを含む。実装の参照コードとして活用してほしい。
Vol1 — X-Ray × OpenTelemetry × Application Signals × ADOT 基礎運用
X-Ray 分散トレーシング / OTel 計装標準化 / Application Signals 初期設定 / ADOT Collector 展開。「何が起きているか」を可視化する基礎編。Vol1 を読む →
Vol2 — CloudWatch Logs深掘り (Insights × Lambda統合 × Centralized × コスト最適化)
Logs Insights 高速分析 / Lambda ログ統合 / Centralized Logging 基盤 (Firehose + S3) / Glacier コスト削減。「なぜ起きたか」をログで追跡する縦深化編。Vol2 を読む →
Vol3 — Application Signals本格 × SLO/SLI × Service Map × CodeGuru Profiler (本記事)
SLO 自動定義 / Error budget 管理 / Service map auto-discovery / Continuous Profiling。「何を守り、どこがボトルネックか」を定義する上位層 + 三部作完結編。
本シリーズ全 3 巻を通じて、AWS 本番運用の監視設計を基礎から上位層まで体系的にマスターできる。Vol1 → Vol2 → Vol3 の順に読み進めるか、本記事を起点に必要な章へ参照してほしい。50 記事化大台達成を機に、Observability 設計の全体像を確認しよう。
▶ 本 Vol3 を読み終えたら §8 のクロスリンクナビで他軸 (Container / Database / AI/ML 等) との接続点を確認することを強く推奨する。AWS マネージドサービスは単独で完結せず、軸を横断して設計することで本番の堅牢性が高まる。
§2 Application Signals 本番運用 — SLO自動定義 × Service map auto-discovery × Latency/Availability × Burn rate ★山場1
2-1. Application Signals の概要と位置付け
AWS Application Signals は、CloudWatch に統合された SLO 管理 + Service Map 自動検出 のフルマネージドサービスだ。2024 年に GA となり、従来は X-Ray + 手動 CloudWatch ダッシュボードで構築していた可観測性スタックを大幅に自動化する。
X-Ray との関係:
- X-Ray はトレースデータの収集・格納・クエリエンジン。「どのリクエストがどのサービスを経由したか」を記録する
- Application Signals は X-Ray のトレースデータを消費し、サービス間の依存関係グラフ (Service Map) の自動構築と SLO 指標 (Latency / Availability) の自動算出を行う
- トレース収集には引き続き ADOT/OTel SDK が必要。Application Signals はその上位レイヤーとして機能する
CloudWatch との統合:
- Application Signals が定義した SLO は CloudWatch Metrics として管理される
- Burn rate アラートは CloudWatch Alarms として設定され、SNS/EventBridge/PagerDuty と連携できる
- CloudWatch Dashboard に Application Signals ウィジェットを埋め込むことで、SLO ステータスをリアルタイム表示できる
対応ランタイム:
| ランタイム | サポート方式 | 備考 |
|---|---|---|
| Java | Auto-instrumentation Agent (CloudWatch Agent 同梱) | ECS/EKS/EC2 対応 |
| Python | Auto-instrumentation (ADOT SDK) | Lambda 含む |
| Node.js | Auto-instrumentation (ADOT SDK) | Lambda 含む |
| .NET | 手動計装 (OTel .NET SDK) | |
| Go | 手動計装 (OTel Go SDK) |

2-2. SLO 自動定義の本番運用パターン
Application Signals では、サービスが ADOT/CloudWatch Agent で計装されると、コンソールから SLO を GUI で定義できる。主要 3 パターンを解説する。
Latency SLO — p99 レイテンシ目標設定
p99 レイテンシ (上位 99% のリクエストが満たすレイテンシ) を SLO として定義するパターン。「平均レイテンシ」ではなく p99 を使う理由は、外れ値 (タイムアウト直前のリクエスト) が SLO に反映されるためだ。
# Application Signals SLO — Latency (概念定義)
slo_name: "OrderService-Latency-p99"
sli_metric:
type: REQUEST_BASED
metric: LATENCY
percentile: p99
goal:
threshold_ms: 300 # p99 レイテンシ 300ms 以内
attainment_goal_percent: 99.9 # SLO: 99.9%
warning_threshold_percent: 99.5
evaluation_period_days: 30
本番設定のポイント:
– threshold_ms は p99 の実績値 × 1.5〜2.0 倍から始め、段階的に引き下げる
– 初期は warning_threshold_percent を低め (99.0%) に設定し、アラート感度を確認してから本番閾値へ移行する
– Lambda のコールドスタートが含まれる場合は p99 が跳ねるため、p95 から始めることも検討する
Availability SLO — HTTP 2xx/5xx 比率
可用性を「成功リクエスト率」として定義するパターン。Application Signals は HTTP ステータスコードを自動収集するため、追加の設定なしに定義できる。
# Application Signals SLO — Availability (概念定義)
slo_name: "OrderService-Availability"
sli_metric:
type: REQUEST_BASED
metric: AVAILABILITY
success_criteria: "HTTP 2xx" # 4xx は除外 (クライアントエラー)
failure_criteria: "HTTP 5xx" # 5xx のみをエラーとカウント
goal:
attainment_goal_percent: 99.9
warning_threshold_percent: 99.5
evaluation_period_days: 30
本番設定のポイント:
– 4xx (クライアントエラー) は SLI に含めない。4xx は入力値の問題であり、サービス品質の指標ではない
– /health など内部ヘルスチェックエンドポイントは除外フィルタを設定する
– 段階的展開 (Blue/Green デプロイ) 中は Burn rate が一時的に上昇するため、デプロイ時間帯のバジェット配分を考慮する
Terraform による SLO 定義
# Application Signals SLO — Terraform
resource "aws_cloudwatch_application_signals_slo" "order_service_latency" {
name = "OrderService-Latency-p99"
description = "Order API p99 latency SLO (300ms / 99.9%)"
sli {
comparison_operator = "LessThanThreshold"
metric_threshold = 300
sli_metric {
type = "RequestBased"
request_based_sli_metric {
total_request_count_metric {
metric_data_queries {
id = "total"
metric_stat {
metric {
namespace= "AWS/ApplicationSignals"
metric_name = "Latency"
dimensions {
name = "Service"
value = "OrderService"
}
}
period = 60
stat= "SampleCount"
}
}
}
monitored_request_count_metric {
good_count_metric {
metric_data_queries {
id = "good"
metric_stat {
metric {
namespace= "AWS/ApplicationSignals"
metric_name = "Latency"
dimensions {
name = "Service"
value = "OrderService"
}
}
period = 60
stat= "p99"
}
}
}
}
}
}
}
goal {
attainment_goal = 99.9
warning_threshold = 99.5
interval {
rolling_interval {
duration= 30
duration_unit = "DAY"
}
}
}
}
2-3. Service Map auto-discovery — 自動依存関係検出
Application Signals の Service Map は、ADOT/CloudWatch Agent のトレースデータを自動解析し、サービス間の呼び出し関係グラフをリアルタイムで構築する。手動設定不要で、新しいサービスが計装されると自動的にマップに追加される。
自動検出の対象:
| コンポーネント | 検出内容 | 備考 |
|---|---|---|
| ECS タスク | サービス名 / タスク定義 / クラスター | ADOT sidecar 必須 |
| EKS Pod | Namespace / Deployment 名 / Service 名 | CloudWatch Agent DaemonSet |
| Lambda 関数 | 関数名 / トリガー (API GW/SQS/S3) | OTel Lambda Layer |
| EC2 インスタンス | アプリケーション名 (タグベース) | CloudWatch Agent |
| RDS / DynamoDB | DB 名 / テーブル名 | アプリ側の OTel DB計装 |
Top contributor 分析:
Service Map の各エッジ (サービス間接続) には Latency / Error rate / Request count が集計表示される。エッジをクリックすると「このサービス間通信でエラー率が高い上位 N 件のエンドポイント」が即座に表示される (Top contributor)。障害の伝播経路を Root cause まで追跡する際、この機能が起点になる。
Service Map の設定例 (EKS):
# CloudWatch Agent ConfigMap — EKS Service Map 有効化
apiVersion: v1
kind: ConfigMap
metadata:
name: amazon-cloudwatch-observability-config
namespace: amazon-cloudwatch
data:
cwagentconfig.json: |
{
"traces": {
"traces_collected": {
"application_signals": {}
}
},
"logs": {
"metrics_collected": {
"application_signals": {
"hosted_in": "MyEKSCluster"
}
}
}
}
2-4. Burn rate アラートの設定と運用
Burn rate アラートは、Error budget の消費速度を監視するアラートだ。SLO 違反が「今どのくらいのペースで起きているか」をリアルタイムで把握し、重大な障害を早期検知する。
Multi-window multi-burn-rate の設計
単一 Burn rate では「検知速度」と「誤報防止」のトレードオフが生じる。Google SRE が標準化した Multi-window multi-burn-rate では、短期窓と長期窓の両方を条件とすることでこのトレードオフを解消する。
| アラート名 | Short window | Long window | Burn rate | 意味 |
|---|---|---|---|---|
| Critical (P1) | 5 分 | 1 時間 | 14.4x | 1h でバジェット全消費ペース → 即応 |
| High (P2) | 30 分 | 6 時間 | 6.0x | 約 5 日でバジェット全消費ペース → 当日対応 |
| Medium (P3) | 2 時間 | 1 日 | 3.0x | 約 10 日でバジェット全消費ペース → 翌日対応 |
| Warning | 6 時間 | 3 日 | 1.0x | SLO 境界 (バジェット正常消費) → 監視継続 |
Short + Long の両方が閾値超過 したときにのみアラートを発報する。Short window だけでは瞬間的なスパイクで誤報が出やすく、Long window だけでは検知が遅れる。
Terraform — CloudWatch Alarm による Burn rate 設定
# Burn rate アラート — Critical (P1): 1h 14.4x
resource "aws_cloudwatch_metric_alarm" "burn_rate_critical_short" {
alarm_name = "OrderService-BurnRate-Critical-Short-1h"
comparison_operator = "GreaterThanThreshold"
evaluation_periods = 1
threshold = 14.4
metric_query {
id = "burnrate"
return_data = true
metric {
namespace= "AWS/ApplicationSignals"
metric_name = "BurnRate"
period= 300 # 5 分 window
stat = "Average"
dimensions = {
SLO = aws_cloudwatch_application_signals_slo.order_service_latency.name
}
}
}
alarm_description = "Critical: Error budget が 1h ペースで全消費中"
alarm_actions= [aws_sns_topic.pagerduty_critical.arn]
ok_actions= [aws_sns_topic.pagerduty_resolve.arn]
treat_missing_data = "notBreaching"
}
resource "aws_cloudwatch_metric_alarm" "burn_rate_critical_long" {
alarm_name = "OrderService-BurnRate-Critical-Long-1h"
comparison_operator = "GreaterThanThreshold"
evaluation_periods = 1
threshold = 14.4
metric_query {
id = "burnrate"
return_data = true
metric {
namespace= "AWS/ApplicationSignals"
metric_name = "BurnRate"
period= 3600 # 1 時間 window
stat = "Average"
dimensions = {
SLO = aws_cloudwatch_application_signals_slo.order_service_latency.name
}
}
}
alarm_description = "Critical: Error budget が 1h 長期ウィンドウで全消費中"
alarm_actions= [aws_sns_topic.pagerduty_critical.arn]
treat_missing_data = "notBreaching"
}
# Composite Alarm: Short + Long の両方が閾値超過で P1 発報
resource "aws_cloudwatch_composite_alarm" "burn_rate_p1" {
alarm_name = "OrderService-BurnRate-P1-Composite"
alarm_rule = join(" AND ", [
"ALARM(${aws_cloudwatch_metric_alarm.burn_rate_critical_short.alarm_name})",
"ALARM(${aws_cloudwatch_metric_alarm.burn_rate_critical_long.alarm_name})"
])
alarm_description = "P1: OrderService Latency SLO — Critical Burn Rate"
alarm_actions = [aws_sns_topic.incident_channel.arn]
}
2-5. CloudWatch Dashboard との統合
Application Signals のウィジェットは CloudWatch Dashboard に追加できる。SLO ステータス (Error budget 残量 / Burn rate) をリアルタイムで表示する標準ウィジェットが用意されており、手動でメトリクスを選択する必要がない。
Dashboard 構成の推奨パターン:
# CloudWatch Dashboard — Application Signals 統合
resource "aws_cloudwatch_dashboard" "observability_main" {
dashboard_name = "Observability-Production-Main"
dashboard_body = jsonencode({
widgets = [
{
type= "metric"
properties = {
title = "OrderService — SLO Error Budget Remaining (%)"
view= "timeSeries"
metrics = [
["AWS/ApplicationSignals", "ErrorBudgetRemaining",
"SLO", "OrderService-Latency-p99"]
]
period = 300
stat= "Average"
yAxis = { left = { min = 0, max = 100 } }
}
},
{
type= "metric"
properties = {
title = "OrderService — Burn Rate (1h window)"
metrics = [
["AWS/ApplicationSignals", "BurnRate",
"SLO", "OrderService-Latency-p99",
{ period = 3600, stat = "Average" }]
]
annotations = {
horizontal = [
{ value = 14.4, label = "Critical threshold", color = "#d62728" },
{ value = 6.0, label = "High threshold", color = "#ff7f0e" }
]
}
}
}
]
})
}
2-6. 本番運用時の注意点
CloudWatch Agent バージョン管理:
Application Signals は CloudWatch Agent の特定バージョン以降でサポートされる。ECS/EKS で展開している場合、CloudWatch Agent の Image tag を固定せず latest を使うと、メジャーアップデート時に互換性問題が生じることがある。
# ECS Task Definition — CloudWatch Agent version 固定
containerDefinitions:
- name: cloudwatch-agent
image: "amazon/cloudwatch-agent:1.300037.1b602"# バージョン固定推奨
essential: false
SDK 互換性:
| OTel SDK | 最小バージョン | Application Signals 対応 |
|---|---|---|
| Java Agent | 1.32.0+ | Auto-instrumentation 対応 |
| Python SDK | 0.43b0+ | ADOT SDK 経由 |
| Node.js SDK | 0.41.0+ | ADOT SDK 経由 |
SDK のマイナーバージョンアップでも互換性が変わる場合があるため、アップグレード前に Staging 環境で Service Map の表示確認と SLO メトリクスの継続性テストを実施すること。
コスト見積:
Application Signals のコストは以下の要素で構成される。
- SLO 評価料金: SLO 1 件あたり月額約 $10〜$15 (リクエスト数依存)
- X-Ray トレース: 100 万トレースあたり $5.00 (最初の 100 万は無料)
- CloudWatch Metrics: カスタムメトリクスとして課金 ($0.30/メトリクス/月)
中規模サービス (SLO 10 件 / 月 1 億リクエスト) の場合、Application Signals 関連コストは月額 $200〜$400 程度を見込む。既存の手動 Dashboard 構築・運用コスト (エンジニア工数) と比較して費用対効果を評価することを推奨する。
鉄則1: SLO は p99 Latency + Availability の両軸で定義する
Latency SLO のみでは HTTP 5xx の増加を検知できない。Availability SLO と両軸で定義することで、レイテンシ劣化とエラー率上昇の両方をカバーする。p99 ベースで定義することで、外れ値 (タイムアウト直前リクエスト) が SLO に反映される。
鉄則2: Service Map auto-discovery を先に有効化してから SLO を定義する
SLO 定義前に Service Map でサービス間依存を確認しておくことで、誤った SLI 境界 (API GW ではなく ECS サービス単体で計測すべき等) のミスを防げる。Service Map → SLO の順で設計する。
鉄則3: Burn rate アラートは Multi-window で設計する (単一 window 禁止)
短期 window (5 分) だけでは瞬間スパイクで誤報が多発する。長期 window (1 時間) だけでは検知が遅れ、Error budget を大量消費してから気づく。Critical (P1) は Short 5 分 + Long 1 時間の Composite Alarm で運用すること。
前提条件の確認
□ ADOT / CloudWatch Agent が対象サービスに展開済みか (未展開の場合は Vol1 参照)
□ X-Ray トレースが CloudWatch に収集されているか (コンソールの X-Ray Traces で確認)
□ Java / Python / Node.js いずれかの対応ランタイムか (.NET / Go は手動計装が必要)
SLO 設計の確認
□ SLI は「Latency p99」と「Availability (HTTP 5xx 比率)」の両方を定義するか
□ Error budget の rolling window は 30 日か (Application Signals デフォルト。変更には注意)
□ Burn rate アラートは Multi-window Composite Alarm (Short + Long) で設計するか
コスト・運用の確認
□ SLO 件数 × 月額コスト ($10〜$15/SLO) が予算内か
□ CloudWatch Agent バージョンを固定管理しているか (latest タグは避ける)
□ Staging 環境で Service Map の表示確認と SLO メトリクスの継続性テストを実施済みか
□ On-call チームが Burn rate (Composite Alarm) の概念を理解しているか
§3 SLO/SLI 管理本番運用 — SLI設計 × Error budget × Multi-window multi-burn-rate × 段階エスカレーション
3-1. SLI / SLO / Error budget の最低知識
SLI (Service Level Indicator) — 4本柱と選び方
SLI とは「サービス品質を数値で計測する指標」であり、何を計測するかによってシステムの信頼性評価の視点が決まる。代表的な SLI の4本柱は Availability / Latency / Error rate / Throughput である。
| SLI 種別 | 計測対象 | 適用サービス例 |
|---|---|---|
| Availability | 正常リクエスト率 (成功 HTTP / 全リクエスト) | API、Web フロントエンド、Lambda |
| Latency | p99 応答時間 (例: 300ms 以下) | レイテンシ敏感な API、DB 接続層 |
| Error rate | 5xx / クライアントエラー比率 | マイクロサービス間通信、外部 API 連携 |
| Throughput | 単位時間あたりの処理数 | バッチ処理、ストリーミング処理 |
SLI 選定の基本方針は「ユーザー体験に直結するものを優先する」ことである。EC サイトでは「カート追加 API の p99 Latency」が「全 API の平均 CPU 使用率」よりもはるかに重要な SLI となる。内部インフラ指標 (CPU/メモリ) は SLI ではなく、診断のためのメトリクスとして区別して管理することが推奨される。
SLO (Service Level Objective) — 目標値設定と運用基準
SLO は SLI に対する目標値であり、どの水準で運用するかを組織として合意した数値である。
| SLO 水準 | 許容ダウンタイム/月 | 適用シーン |
|---|---|---|
| 99.9% (Three-9s) | 約 43 分/月 | 社内ツール、開発環境、バッチ系 |
| 99.95% | 約 22 分/月 | 一般的な本番 API、中規模 SaaS |
| 99.99% (Four-9s) | 約 4.3 分/月 | 決済、医療、基幹ミッションクリティカル |
SLO は「できる限り高く設定する」ものではなく、ビジネス要件と運用コストのバランスで決定する。99.99% を目指すには冗長化・自動フェイルオーバー・高度なオンコール体制が必要となり、コストが指数的に増加する。まず 99.9% から始め、インシデント実績をもとに段階的に引き上げるアプローチが現実的だ。
Error budget — 消費率管理と開発速度バランス
Error budget とは「SLO を達成するために許容できるエラー/ダウンタイムの残量」である。SLO が 99.9% の場合、1ヶ月の Error budget は約 43.2 分となる。
Error budget の活用方針は消費率によって4段階で変化する。
- budget 十分 (消費率 < 50%): 積極的にデプロイ・実験可能。新機能リリースを優先する
- budget 警戒 (消費率 50%〜80%): 変更管理を強化。リリース前レビューを必須化する
- budget 凍結 (消費率 80%〜100%): 新機能デプロイを停止。信頼性改善タスクのみ許可
- budget 枯渇 (消費率 100% 超): 緊急フリーズ。全デプロイ禁止・SRE 優先対応
Error budget を「罰則」ではなく「デプロイ判断の共通言語」として位置づけることで、開発速度と信頼性の対立を客観的な数値で解消できる。
3-2. Multi-window multi-burn-rate アラート設計
単一の閾値アラート (例: エラー率 1% 超で通知) には2つの根本的な問題がある。1つ目は「瞬間的なスパイク」による誤検知の多発、2つ目は「ゆっくりとした Error budget 枯渇」の見逃しである。これを解決するのが Multi-window multi-burn-rate アラート設計だ。
Burn rate の概念
Burn rate (燃焼率) とは「Error budget を消費するペース」を表す指数であり、1.0 が「SLO で定めた許容ペースで消費している」状態、14.4 なら「同じペースが続けば月次バジェットを 1/14.4 の時間で使い切る」ことを意味する。
4段階の Burn rate 閾値設計
| アラート | Short window | Long window | Burn rate | 通知先 | 月 budget 消費目安 |
|---|---|---|---|---|---|
| Page (Sev1) | 1h | 5m | 14.4x | PagerDuty 即時起床 | 1h で 2% 消費 |
| Page (Sev2) | 6h | 30m | 6x | PagerDuty 時間外も通知 | 6h で 5% 消費 |
| Ticket | 24h | 2h | 3x | Slack + チケット | 24h で 10% 消費 |
| Monitor | 72h | 6h | 1x | Slack のみ | 定常ペース監視 |
各アラートは Short window で感度を、Long window で確度を確認する「2条件 AND」構成が標準である。Short window だけでは瞬間スパイクで誤発報が多発し、Long window だけでは緊急ケースの検知が遅延する。
CloudWatch Composite Alarm による実装 (Terraform)
# Burn rate 14.4x (1h) — Sev1 Page アラーム
resource "aws_cloudwatch_metric_alarm" "slo_burn_1h" {
alarm_name = "slo-${var.service_name}-burn-1h-14x"
comparison_operator = "GreaterThanThreshold"
evaluation_periods = 1
threshold = 0.144
metric_query {
id = "error_rate"
expression = "errors / requests"
label = "Error Rate"
return_data = true
}
metric_query {
id = "errors"
metric {
metric_name = "5xxErrorCount"
namespace= "AWS/ApplicationSignals"
period= 3600
stat = "Sum"
dimensions = { ServiceName = var.service_name }
}
}
metric_query {
id = "requests"
metric {
metric_name = "RequestCount"
namespace= "AWS/ApplicationSignals"
period= 3600
stat = "Sum"
dimensions = { ServiceName = var.service_name }
}
}
alarm_actions = [aws_sns_topic.pagerduty_sev1.arn]
ok_actions = [aws_sns_topic.pagerduty_sev1.arn]
tags = var.tags
}
# Burn rate 6x (6h) — Sev2 Page アラーム
resource "aws_cloudwatch_metric_alarm" "slo_burn_6h" {
alarm_name = "slo-${var.service_name}-burn-6h-6x"
comparison_operator = "GreaterThanThreshold"
evaluation_periods = 1
threshold = 0.060
metric_query {
id = "error_rate"
expression = "errors / requests"
label = "Error Rate"
return_data = true
}
metric_query {
id = "errors"
metric {
metric_name = "5xxErrorCount"
namespace= "AWS/ApplicationSignals"
period= 21600
stat = "Sum"
dimensions = { ServiceName = var.service_name }
}
}
metric_query {
id = "requests"
metric {
metric_name = "RequestCount"
namespace= "AWS/ApplicationSignals"
period= 21600
stat = "Sum"
dimensions = { ServiceName = var.service_name }
}
}
alarm_actions = [aws_sns_topic.pagerduty_sev2.arn]
tags = var.tags
}
# Composite Alarm — Short window AND Long window の2条件 AND
resource "aws_cloudwatch_composite_alarm" "slo_burn_page" {
alarm_name = "slo-${var.service_name}-page-composite"
alarm_rule = join(" AND ", [
"ALARM(\"${aws_cloudwatch_metric_alarm.slo_burn_1h.alarm_name}\")",
"ALARM(\"${aws_cloudwatch_metric_alarm.slo_burn_5m.alarm_name}\")",
])
alarm_actions = [aws_sns_topic.pagerduty_sev1.arn]
tags = var.tags
}
アラート疲労防止チューニング
アラートが多すぎると「アラート疲労 (Alert fatigue)」が発生し、重大インシデントが見落とされる。
- Evaluation period 延長: Short window の evaluation_periods を 2〜3 に増やし、連続2回超過で発報する
- Composite alarm: 単一メトリクス超過ではなく、複数条件の AND/OR 組み合わせで誤検知を削減する
- Suppressor alarm: メンテナンス時間帯に他のアラームを自動抑制する Composite alarm suppressor を設定する
- Burn rate 1x は Slack のみ: Sev4 相当の低 burn rate は PagerDuty を鳴らさず、Slack チャンネルへのみ通知する

① SLI は4本柱から「ユーザー体験直結」のものを選べ
Availability / Latency / Error rate / Throughput のうち、ユーザーが最初に痛みを感じる指標を主 SLI に選ぶ。内部インフラ指標 (CPU/メモリ) は SLI ではなく診断メトリクスとして区別する。
② Error budget は「デプロイ判断の共通言語」として明文化せよ
消費率 80% 超でデプロイ凍結・100% 超で緊急フリーズを組織ルールとして明文化する。budget を「罰則」ではなく「速度と信頼性のトレードオフ指標」として全エンジニアに周知する。
③ Multi-window multi-burn-rate は「Short AND Long の2条件」で構成せよ
Short window (1h/6h) で感度、Long window (5m/30m) で確度を検証する Composite alarm を構成する。単一閾値アラートは誤検知と見逃しの両方を招く構造的な欠陥がある。
3-3. CloudWatch Application Signals での SLO 管理操作手順
コンソール操作手順
1. CloudWatch コンソール → [Application Signals] → [SLOs] → [Create SLO]
2. SLO 名を入力 (例: checkout-api-availability-slo)
3. SLI タイプを選択: Availability / Latency
4. サービス選択: Application Signals で検出済みのサービス一覧から選択
5. 目標値設定:
- Attainment goal: 99.9%
- Warning threshold: 99.5% (オプション)
- Period: Rolling 30d (または Calendar month)
6. アラーム設定:
- Burn rate 14.4x → SNS Topic (PagerDuty)
- Burn rate 6x → SNS Topic (Slack)
7. [Create SLO] で作成完了
SLO ダッシュボードで確認できる主要指標
| 指標 | 説明 |
|---|---|
| Current attainment | 現在の達成率 (rolling 30d / calendar month) |
| Error budget remaining | 残 Error budget (%) |
| Budget burndown | 時系列での budget 消費グラフ |
| Breached windows | 過去の SLO ブリーチ記録 |
3-4. Error budget ポリシーの実践
段階的なデプロイ制御マトリクス
Error budget 消費率デプロイ方針 変更審査レベル
─────────────────────────────────────────────────────────────────────
0% 〜 50%通常デプロイ可 軽微なレビューのみ
50% 〜 80% 変更管理強化プレリリースレビュー必須
80% 〜 100% 凍結: 信頼性改善のみ SRE チームリード承認必須
100% 超 緊急フリーズ 全デプロイ禁止 (ホットフィックスのみ)
毎月の月次レビューでは以下の3点を確認する。
- SLO 達成率: 各サービスが SLO を達成できたか確認し、未達成サービスの根本原因を特定する
- Budget 消費パターン: どのインシデントが最大の budget を消費したかを分析し、再発防止策を策定する
- SLO 目標値の見直し: 過去3ヶ月のデータをもとに SLO が適切な挑戦レベルかを検討し、必要に応じて調整する
CDK での Error budget 警告アラーム (Python)
from aws_cdk import (
Duration,
aws_cloudwatch as cw,
)
budget_alarm = cw.Alarm(
self,
"ErrorBudgetWarning",
alarm_name=f"slo-{service_name}-budget-80pct",
metric=cw.MathExpression(
expression="1 - (errors / requests)",
using_metrics={
"errors": error_metric,
"requests": request_metric,
},
period=Duration.days(30),
),
comparison_operator=cw.ComparisonOperator.LESS_THAN_THRESHOLD,
threshold=0.9992,
evaluation_periods=1,
alarm_description=f"{service_name}: Error budget 80% 消費警告",
actions_enabled=True,
)
3-5. 実運用事例: SLO ブリーチ時の対応フロー
フェーズ1: 検知 → 初動 (0〜5分)
1. PagerDuty 通知 → オンコール担当が Ack
2. Application Signals ダッシュボードで確認:
- どのサービスの SLO がブリーチしているか
- Latency / Availability / Error rate のうちどれが原因か
3. Service Map で依存関係を確認し、根本原因サービスを特定
4. 影響範囲の見積もり (ユーザー影響数 / 顧客ティア)
フェーズ2: 緩和 → 復旧 (5〜30分)
5. 直近デプロイがある場合 → 即時ロールバック判断
6. インフラ障害の場合 → AZ フェイルオーバー / スケールアウト
7. Error budget 凍結宣言 → 新規デプロイ禁止を Slack #engineering で周知
8. CloudWatch アラームの ALARM → OK への遷移を確認
フェーズ3: 事後対応 (24〜48時間)
9. Error budget 消費量の計算と月次残量の確認
10. 根本原因分析 (5 Whys)
11. 再発防止策の策定とチケット起票
12. SLO アラート設計の見直し (誤検知だった場合は閾値調整)
□ 1h window Burn rate 14.4x: 月 budget の 2% を1時間で消費するペース → PagerDuty Sev1 (即時起床)
□ 6h window Burn rate 6x: 月 budget の 5% を6時間で消費するペース → PagerDuty Sev2 (時間外も通知)
□ 24h window Burn rate 3x: 月 budget の 10% を24時間で消費するペース → Slack + チケット
□ 72h window Burn rate 1x: 定常ペース → Slack #observability (監視のみ)
□ Composite alarm (2条件 AND): Short window AND Long window の両方が超過で発報する構成になっているか
□ Suppressor alarm: メンテナンス時間帯の自動アラーム抑制を設定済みか
□ Error budget ポリシー文書化: 消費率に応じたデプロイ判断基準を組織全体で合意・周知済みか
□ 月次 SLO レビュー: SLO 達成率・budget 消費パターンの月次レビュー会議を設定済みか
§4 Service Map 本番運用 — 依存関係可視化 × Top contributor × Cross-account × Hybrid environment
4-1. Service Map の仕組みと自動検出原理
Service Map は Application Signals が自動生成する依存関係グラフであり、マイクロサービス間のトレースデータをリアルタイムに集約して可視化する機能である。
自動検出の仕組み
Application Signals が有効化されたサービスは、X-Ray SDK / ADOT Collector / CloudWatch Agent を通じてサービス呼び出しのトレースデータを送信する。Service Map はこのトレースデータを解析し、サービス間の呼び出し関係・レイテンシ・エラー率をグラフ構造として自動構築する。
[Service Node]
サービス名 (ServiceName dimension)
エンドポイント種別 (ECS Task / Lambda / EKS Pod / EC2 / RDS)
呼び出し元 / 呼び出し先の関係性
レイテンシ / エラー率 / スループットの集計値
[Edge (矢印)]
呼び出し頻度 (矢印の太さで表現)
p99 レイテンシ
エラー率
遅延ホットスポットの色分け (緑 → 黄 → 赤)
サポートされる自動検出対象
| 環境 | 自動検出方法 |
|---|---|
| Amazon ECS | CloudWatch Container Insights + ADOT サイドカー |
| Amazon EKS | ADOT Operator / CloudWatch Observability Add-on |
| AWS Lambda | Lambda Insights + X-Ray アクティブトレース |
| Amazon EC2 | CloudWatch Agent + X-Ray Daemon |
| Amazon RDS | Performance Insights + RDS プロキシトレース |
4-2. 依存関係可視化の実践
サービスグラフの読み方
Service Map の各ノードは以下の色分けで健全性を表示する。
緑 (Normal) : エラー率 < 5% / レイテンシ SLO 以内
黄 (Degraded) : エラー率 5%〜20% / レイテンシ SLO の 150%〜200%
赤 (Error) : エラー率 > 20% / レイテンシ SLO の 200% 超 / Burn rate アラーム発報中
灰 (Unknown): トレースデータ未受信 (Agent 未設定 / ネットワーク問題)
ノードをクリックすると、そのサービスの SLO 達成率・Error budget 残量・直近インシデントが表示される。エッジ (矢印) の太さは呼び出し頻度を、色は遅延ホットスポットを表す。
遅延ホットスポット特定の手順
1. Service Map を開き、赤または黄のノードを確認する
2. 赤ノードをクリック → [View traces] で問題のトレースを開く
3. トレースウォーターフォール図で遅延発生箇所を特定する
- 全体の 80% 以上の時間を占めるセグメントが根本原因
4. [Analyze top contributors] タブで遅延増加に寄与しているサービスを確認する
5. 原因サービスの CloudWatch メトリクスを詳細調査する
Top contributor 分析手順
Top contributor は「全体の遅延増加に最も寄与しているサービス」を自動ランキングする機能である。
1. CloudWatch コンソール → [Application Signals] → [Service Map]
2. 上部の [Top contributors] タブを選択する
3. メトリクス種別を選択: Latency / Error rate / Throughput
4. 集計期間を指定 (例: 直近1時間 / 直近24時間)
5. ランキング上位のサービスをクリックして詳細分析を実施する
4-3. Cross-account Service Map 設定
大規模なマイクロサービス環境では、複数の AWS アカウントにサービスが分散していることが多い。CloudWatch クロスアカウントオブザーバビリティを使用すると、複数アカウントの Service Map を1つのモニタリングアカウントから統合表示できる。
ステップ1: モニタリングアカウント側の設定 (OAM Sink 作成)
resource "aws_oam_sink" "central" {
provider = aws.monitoring_account
name = "central-observability-sink"
policy = jsonencode({
Version = "2012-10-17"
Statement = [{
Effect = "Allow"
Principal = { AWS = var.source_account_ids }
Action = ["oam:CreateLink", "oam:UpdateLink"]
Resource = "*"
Condition = {
"ForAllValues:StringEquals" = {
"oam:ResourceTypes" = [
"AWS::ApplicationSignals::Service",
"AWS::XRay::Trace",
]
}
}
}]
})
}
ステップ2: ソースアカウント側の設定 (各サービスアカウント)
resource "aws_oam_link" "source_account" {
label_template = "$AccountName"
resource_types = [
"AWS::ApplicationSignals::Service",
"AWS::XRay::Trace",
]
sink_identifier = var.monitoring_account_sink_arn
}
Organizations 統合による一括設定 (CloudFormation StackSets)
AWSTemplateFormatVersion: "2010-09-09"
Parameters:
MonitoringAccountId:
Type: String
Region:
Type: String
Default: ap-northeast-1
Resources:
OAMLink:
Type: AWS::Oam::Link
Properties:
LabelTemplate: "$AccountName"
ResourceTypes:
- "AWS::ApplicationSignals::Service"
- "AWS::XRay::Trace"
SinkIdentifier: !Sub "arn:aws:oam:${Region}:${MonitoringAccountId}:sink/central-observability-sink"
設定完了後、モニタリングアカウントの CloudWatch コンソール → Service Map を開くと、全ソースアカウントのサービスが統合表示される。アカウント境界を越えたサービス間の依存関係も矢印で可視化され、問題の伝播経路を特定しやすくなる。

① 依存関係可視化は「トレースデータの自動集約」で完成させよ
全サービスに ADOT / X-Ray SDK を設定し、ServiceName dimension を統一する。手動でノードを追加するのではなく、トレースデータが正しく送信されることで Service Map は自動的に正確になる。
② Top contributor で「遅延増加の根本原因」を5分以内に特定せよ
インシデント発生時、全トレースを手動確認する前に Top contributor タブを開く。ランキング上位1〜3件が大多数のケースで根本原因サービスである。
③ Cross-account は OAM Sink/Link で統合し、アカウント境界を透明にせよ
複数アカウントの Service Map を1つのモニタリングアカウントに集約する。各チームが個別ダッシュボードを管理する「サイロ型」から脱却し、組織全体の依存関係を俯瞰する体制を構築する。
4-4. Hybrid environment 対応
オンプレミスエージェント接続 (CloudWatch Agent + ADOT)
オンプレミスサーバーやデータセンター内のサービスも Service Map に統合できる。以下は CloudWatch Agent 設定ファイルの例である。
{
"agent": {
"metrics_collection_interval": 60,
"run_as_user": "cwagent"
},
"traces": {
"traces_collected": {
"xray": {
"bind_address": "127.0.0.1:2000",
"tcp_proxy": { "bind_address": "127.0.0.1:2000" }
},
"otlp": {
"grpc_endpoint": "127.0.0.1:4317",
"http_endpoint": "127.0.0.1:4318"
}
}
}
}
オンプレミスから CloudWatch にトレースを送信するには以下が必要となる。
- AWS 認証情報 (IAM ユーザーまたは AssumeRole) の設定
- アウトバウンドの HTTPS (443) 通信許可 (CloudWatch エンドポイントへ)
- ServiceName の統一 (AWS 側サービスと同一の命名規則)
外部 API 監視の組み込み
外部 API (決済ゲートウェイ / SMS プロバイダー等) も Service Map のノードとして表示できる。X-Ray SDK の subsegment を使用し、外部呼び出し部分をトレースに含める。
from aws_xray_sdk.core import xray_recorder
import requests
@xray_recorder.capture("external-payment-api")
def call_payment_gateway(payload: dict) -> requests.Response:
subsegment = xray_recorder.current_subsegment()
subsegment.put_annotation("api_provider", "stripe")
subsegment.put_annotation("operation", "charge")
response = requests.post(
"https://api.stripe.com/v1/charges",
data=payload,
timeout=5.0,
)
subsegment.put_metadata("response_status", response.status_code)
return response
4-5. Service Map ノイズ削減
大規模マイクロサービス環境では、Service Map に数百のノードが表示されて可読性が低下することがある。
低頻度サービスの除外フィルタ
CloudWatch コンソール → Service Map → [Filter]
→ 「Minimum request rate」を設定 (例: 1 req/min 以下のサービスを非表示)
→ 「Service type」フィルタ (例: Database のみ表示 / Internal サービスを非表示)
→ 「Environment」タグフィルタ (例: production 環境のみ)
ServiceName の設計原則
ノイズの根本原因は、サービス名の粒度が適切でないことが多い。
粒度が粗すぎる (避けるべき): "backend-service" → Service Map に1ノードしか表示されない
粒度が細かすぎる (避けるべき): "backend-pod-abc123" → Pod 数だけノードが増殖する
推奨設計:
"checkout-api" / "payment-processor" / "inventory-service" (機能単位)
EKS: Deployment 名を ServiceName に使用する
Lambda: 関数プレフィックスでグルーピング (例: "order-" → "order-service")
4-6. アラートとの連携
Service Map の異常検知を EventBridge 経由で Slack へ自動通知するパターンを示す。
resource "aws_cloudwatch_event_rule" "service_map_degradation" {
name = "service-map-slo-breach-alert"
description = "SLO ブリーチ発生時に Slack へ通知"
event_pattern = jsonencode({
source = ["aws.cloudwatch"]
"detail-type" = ["CloudWatch Alarm State Change"]
detail = {
state = { value = ["ALARM"] }
alarmName = [{ prefix = "slo-" }]
}
})
}
resource "aws_cloudwatch_event_target" "slack_notifier" {
rule= aws_cloudwatch_event_rule.service_map_degradation.name
target_id = "SlackNotifier"
arn = aws_lambda_function.slack_notifier.arn
}
Pod 単位トレースによるノード爆発: EKS Pod 名でトレースが作成されると、Pod スケールアウト時に Service Map のノード数が急増する。ServiceName は Pod 名ではなく Deployment 名に統一すること。
External サービスのノード爆発: 外部 API の URL が動的に変化する場合 (例: CDN エッジノード) は、X-Ray SDK の URL グルーピング設定を使用して同一サービスとして集約する。設定なしだと数百ノードが生成されることがある。
Development / Staging 環境の混入: ServiceName に環境情報を含めない場合、開発環境のトレースが本番 Service Map に混入する。environment:production タグフィルタを必ず設定し、環境を分離すること。
フィルタの過剰適用: ノイズ削減のためフィルタを厳しくしすぎると、本番の重要なサービスが Service Map から消える。フィルタ変更後は必ず手動確認を実施すること。
§5 CodeGuru Profiler 本番運用 — Continuous Profiling × Hot path特定 × Cost optimization × Heap summary ★山場2
CodeGuru Profiler を本番環境に展開する際、最初に湧く懸念は 「Agent がアプリケーションに与えるオーバーヘッド」 だ。実測値では CPU overhead は平均 1% 未満 に収まる設計になっており、スタックサンプリング方式のため連続リクエストのレイテンシには直接影響しない。Sampling interval のデフォルト設定は 5 ミリ秒であり、高トラフィック環境での調整例は以下の通りだ。
// Java Agent — Sampling interval の明示指定 (デフォルト 5ms / overhead < 1%)
CodeGuruProfilerAgent agent = new CodeGuruProfilerAgent(
new AgentConfiguration.Builder()
.samplingIntervalInMilliseconds(5)
.minimumTimeForReportingInMilliseconds(60_000)
.build()
);
この事実を基準に「本番投入 ≒ 安全」という判断軸を確立してから設定を進めよう。
5-1. CodeGuru Profiler のアーキテクチャ
CodeGuru Profiler は 継続的サンプリング方式 (Continuous Profiling) を採用する。スタックトレースを一定間隔でサンプリングして集約し、AWS バックエンドへ送信する。収集データはリアルタイムで フレームグラフ (Flame Graph) および コールツリー (Call Tree) として可視化される。
Application Runtime
│
▼
CodeGuru Agent (In-process / Sidecar)
┌──────────────────────────────────────┐
│ Stack Sampler (5ms interval) │
│ ├── Capture current call stacks│
│ └── Aggregate into profile buffer │
└────────────────────┬─────────────────┘
│ HTTPS (TLS 1.2+)
▼
CodeGuru Profiler Service
┌───────────────────────────┐
│ Profile Storage │
│ Aggregation Engine │
│ Recommendations Engine│
└───────────────┬───────────┘
│
┌─────────┴──────────────┐
▼▼
Flame Graph UI CloudWatch Insights
(Hot path 可視化)(Recommendations 自動提案)
対応ランタイムは Java / Python / Node.js / Ruby / Go / .NET の 6 種類。Java のみ Heap Summary (ヒープ使用量の時系列分析) も利用可能だ。
5-2. Profiling Group の設定と本番運用
Profiling Group は アプリケーション単位 で作成する。1 Group に複数インスタンスを集約することでフリートレベルのホットスポット特定が可能になる。
Terraform によるリソース定義:
resource "aws_codeguruprofiler_profiling_group" "api" {
name = "production-api-profiler"
compute_platform = "Default"
agent_orchestration_config {
profiling_enabled = true
}
tags = {
Environment = "production"
Service = "api"
}
}
resource "aws_iam_policy" "codeguru_profiler_agent" {
name = "CodeGuruProfilerAgentPolicy"
policy = jsonencode({
Version = "2012-10-17"
Statement = [
{
Effect = "Allow"
Action = [
"codeguru-profiler:ConfigureAgent",
"codeguru-profiler:PostAgentProfile"
]
Resource = aws_codeguruprofiler_profiling_group.api.arn
}
]
})
}
ECS への組み込み (Java In-process Agent):
[
{
"name": "api",
"image": "your-api-image:latest",
"environment": [
{
"name": "AWS_CODEGURU_PROFILER_GROUP_NAME",
"value": "production-api-profiler"
},
{
"name": "AWS_CODEGURU_PROFILER_ENABLED",
"value": "true"
},
{
"name": "AWS_REGION",
"value": "ap-northeast-1"
}
]
}
]
Lambda への組み込み (Python Lambda Layer 方式):
import codeguru_profiler_agent
@codeguru_profiler_agent.with_lambda_profiler(
profiling_group_name="production-lambda-profiler"
)
def handler(event, context):
return process(event)
EKS への組み込み (Java Agent — initContainer 方式):
apiVersion: apps/v1
kind: Deployment
metadata:
name: api-deployment
spec:
template:
spec:
initContainers:
- name: copy-agent
image: public.ecr.aws/codeguru/aws-codeguru-profiler-java-agent-standalone:latest
command: ["cp", "/agent/aws-codeguru-profiler.jar", "/opt/codeguru-profiler/"]
volumeMounts:
- name: codeguru-agent
mountPath: /opt/codeguru-profiler
containers:
- name: api
env:
- name: AWS_CODEGURU_PROFILER_GROUP_NAME
value: "production-api-profiler"
- name: JAVA_TOOL_OPTIONS
value: "-javaagent:/opt/codeguru-profiler/aws-codeguru-profiler.jar"
volumeMounts:
- name: codeguru-agent
mountPath: /opt/codeguru-profiler
volumes:
- name: codeguru-agent
emptyDir: {}
EC2 への適用は環境変数の追加と JAR ファイルの -javaagent 指定のみで完結する。
5-3. Hot path 特定の実践

フレームグラフは CPU 使用時間を可視化した逆木構造 だ。横軸がサンプル数 (= CPU 使用比率)、縦軸がコールスタック深さを表す。「底辺が広いブロック = そのメソッドで CPU を長く消費している」が Hot path の直感的な判断基準になる。
フレームグラフの読み方 — 3 ステップ:
Step 1: 底辺が広いブロックを探す
例: com.example.api.UserService.processRequest — 35% CPU
Step 2: スタックを上方向にたどり「実際の処理」を特定する
processRequest
└── fetchFromDatabase (JDBC call) — 28% CPU ← HOT PATH
└── com.mysql.jdbc.PreparedStatement.execute
Step 3: 外部 I/O (DB/HTTP) vs CPU 演算を区別する
DB 呼び出しが Hot path → N+1 クエリ or インデックス欠如を疑う
CPU 演算が Hot path→ アルゴリズム最適化 or キャッシュ導入を検討
レイテンシ増加の根本原因特定手順:
1. Application Signals で p99 レイテンシ増加アラートを受信
2. CloudWatch → CodeGuru Profiler の時刻を一致させて当該時間帯プロファイルを開く
3. Flame Graph で問題エンドポイントの Hot path を特定
4. Call Tree ビューで「呼び出し回数 × 所要時間」を確認
5. Top Down / Bottom Up 切り替えでボトルネック層を絞り込む
- 本番 Agent を常時有効化する: Continuous Profiling の CPU overhead は < 1% 設計。開発・ステージング・本番を同一設定にすることで、本番固有のボトルネックを検出できる。
- フレームグラフで Hot path を差分比較する: デプロイ前後のプロファイルを並べ、本番固有の Wide Block (CPU 消費が高いメソッド) を起点に根本原因を掘り下げる。Lambda / ECS / EKS いずれも同一ワークフローで分析可能。
- Cost optimization の起点として使う: コスト増加の多くは「非効率な CPU/Memory 消費」に起因する。Profiler レポートにはコスト見積も含まれており、Hot path 改善 → CPU 削減 → Fargate/EC2 コスト削減に直結する。
5-4. Cost optimization 活用
Recommendations レポートが自動検出する コスト増加コードパターン と対処法:
| パターン | 検出例 | 対処法 |
|---|---|---|
| 非効率ループ | for 内の String += 連結 (Java) | StringBuilder に置換 → GC 圧力軽減 |
| 同期ブロック競合 | synchronized への高頻度アクセス | Lock-free 設計 or ConcurrentHashMap へ移行 |
| 反復 JSON 解析 | リクエストごとに全 JSON をデシリアライズ | キャッシュ + 差分更新パターンへ移行 |
| 不要な Reflection | Class.forName / Method.invoke の繰り返し | 起動時に一度だけ解決して static キャッシュ |
| コネクション枯渇 | DB コネクションプール待機による CPU 増大 | maximumPoolSize チューニング |
最適化前後の比較 — Profiler 差分レポート活用:
Before 最適化:
UserService.fetchUsers → 42% CPU (Hot path)
└── HibernateTemplate.find (N+1 クエリ: 150 DB calls / リクエスト)
After 最適化 (Batch fetch + キャッシュ):
UserService.fetchUsers → 8% CPU
└── HibernateTemplate.find (1 DB call / リクエスト)
削減効果: CPU 使用率 -81% → Fargate vCPU コスト -30% (月次見積)
Profiler の Time series 比較 を使うことで、デプロイ前後のプロファイルを並べて Hot path の改善効果を定量的に確認できる。
5-5. Heap summary 活用 (メモリリーク検出)
Java ランタイムでは Heap Summary 機能によりヒープ使用量の時系列推移とオブジェクト生存分析が可能だ。Python では Memory snapshot 機能で肥大化クラスを特定できる。
メモリリーク検出フロー (Java):
Step 1: Heap Summary でヒープ使用量が右肩上がり継続を確認
Step 2: GC 後も Old Gen 使用率が下がらない → 未解放オブジェクトを疑う
Step 3: Top Objects 一覧で「生存数が単調増加するクラス」を特定
例: ConcurrentHashMap$Node — 1.2M → 2.4M → 4.8M (2 倍ペースで増加)
Step 4: コードレビューで当該クラスの remove / evict 処理欠如を確認
Step 5: キャッシュ上限 (MaxSize) と TTL 設定を追加してデプロイ
Step 6: Heap Summary 再確認 — 生存数が安定すれば修正完了
Python Memory snapshot の活用:
# CodeGuru Profiler が非同期で Memory snapshot を収集する
# "Top Allocations" レポートから肥大化クラスを特定可能
import codeguru_profiler_agent
@codeguru_profiler_agent.with_lambda_profiler(
profiling_group_name="production-lambda-profiler"
)
def handler(event, context):
# CodeGuru が自動でメモリ使用パターンをサンプリング
return process(event)
OOMKilled への対処フロー:
OOMKilled 発生
│
▼
1. Heap Summary でメモリ増加トレンドを確認
│
├── 急増 (数分で OOM) → Large Object Allocation を確認
│ └── 画像/CSV 全件ロードなど大きなオブジェクトが原因
│ → Streaming 処理 / Pagination へ切り替え
│
└── 緩慢増加 (数時間で OOM) → メモリリークを確認
└── キャッシュ未 evict / 循環参照 / EventListener 未解除
→ TTL 設定 / WeakReference / removeEventListener
5-6. Multi-account 集約 (Organizations ResourceGroups 連携)
複数 AWS アカウントにまたがるマイクロサービスを一元管理するには Organizations ResourceGroups 経由でプロファイルを集約し、管理アカウントから横断閲覧できる構成を取る。
resource "aws_resourcegroups_group" "codeguru_fleet" {
name = "codeguru-profiler-fleet"
resource_query {
query = jsonencode({
ResourceTypeFilters = ["AWS::CodeGuruProfiler::ProfilingGroup"]
TagFilters = [
{
Key = "Environment"
Values = ["production"]
}
]
})
}
}
Cross-account アクセスには Profiling Group の Resource-based policy を設定する:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::MANAGEMENT_ACCOUNT_ID:root"
},
"Action": [
"codeguru-profiler:GetProfile",
"codeguru-profiler:ListProfileTimes"
],
"Resource": "arn:aws:codeguru-profiler:ap-northeast-1:MEMBER_ACCOUNT_ID:profilingGroup/production-api-profiler"
}
]
}
5-7. Profile diff 解釈のコツ
Profile diff は A/B デプロイ比較 や デプロイ前後比較 で使う最も強力な機能の一つだ。ただし比較条件を揃えないと誤検知 Hot path が多発する。
誤検知回避のための比較条件:
統一すべき条件:
✅ 同一トラフィックパターンの時間帯を選ぶ (ピーク vs ピーク)
✅ 同一インスタンスタイプ / vCPU 数を揃える
✅ プロファイル収集期間を同じにする (最低 5 分)
✅ JIT コンパイル完了後のデータを使う (起動直後は Warm-up バイアスあり)
避けるべき比較:
❌ 深夜 vs 日中 (トラフィック差異で CPU 利用率自体が異なる)
❌ スケールアウト中のインスタンスと安定インスタンスの混在
A/B デプロイ比較の実践:
Blue (旧バージョン) vs Green (新バージョン) 比較手順:
1. Blue でプロファイル収集 (5-10 分)
2. Green デプロイ後、Warm-up 完了まで待機 (ECS: 約 3 分)
3. Green で同じ期間プロファイル収集
4. Profiler Console → Compare profiles で Blue / Green を選択
5. "New Hot path" = Green 固有の新ボトルネック → デプロイ前に修正
6. "Removed Hot path" = 改善済みの証拠 → デプロイ判断の根拠に活用
5-8. CloudWatch Recommendations 自動提案の活用
CodeGuru Profiler は収集したプロファイルデータを機械学習で分析し、改善推奨 (Recommendations) を自動生成する。推奨は 3 カテゴリに分類される:
| カテゴリ | 例 | 改善効果 |
|---|---|---|
| AWS ベストプラクティス | AmazonS3 クライアントのシングルトン化 | API 接続確立コスト削減 |
| パフォーマンス問題 | Collections.sort() ループ内呼び出し | 呼び出し元に移動して O(n log n) 削減 |
| コスト最適化 | Thread.sleep() スピンウェイト検出 | Event-driven 設計への移行推奨 |
Recommendations は 重大度 (Critical / High / Medium / Low) でランク付けされる。Critical から優先的に対処し、次のデプロイ後に再確認するサイクルを確立することがポイントだ。
- 高負荷バースト時のサンプリングスキップ: Agent はスレッドの CPU 使用率が 90% を超えるとサンプリングを自動スキップする設計のため、極端な高負荷ピーク直後にプロファイルデータが薄くなる場合がある。アラーム発生直後のプロファイルが少ない場合はこれが原因。
- Sampling rate の誤解: 「5ms サンプリング」はスレッドを 5ms ごとに一時停止するのではなく、5ms 毎にスタックスナップショットを取る非侵襲的な方式。アプリケーションのレイテンシに直接加算されない。
- Lambda の Cold start 増加: Lambda に Agent を組み込むと Cold start 時間が 100-200ms 増加する場合がある。厳格なレイテンシ要件がある関数では Provisioned Concurrency との組み合わせを検討するか、Agent を無効化する判断も必要。
- Fargate Spot でのデータ欠損: Fargate Spot タスクが中断されると Agent のバッファが未送信のまま消失する。重要な Profiling Group は On-Demand タスクで収集し、Spot は補助的な位置づけにする設計が安全。
§6 詰まりポイント7選 図解 (Mermaid01 判断ツリー)
Application Signals × SLO/SLI × Service Map × CodeGuru Profiler を本番に導入すると、特定パターンのトラブルに必ずぶつかる。7選の詰まりを体系化し、判断ツリーで根本原因まで一直線にたどれるよう整理した。
flowchart TD
START[📍 詰まり症状が発生] --> Q1{どのサービスの問題?}
Q1 -->|Application Signals / SLO| Q2{SLO達成できない?}
Q1 -->|Service Map| Q3{Service Mapが見づらい?}
Q1 -->|CodeGuru Profiler| Q4{Profilerで問題?}
Q2 -->|Error budget 枯渇が早い| T1[詰まり1: SLO定義罠<br/>目標値高すぎ]
Q2 -->|アラートが頻発する| T2[詰まり2: Burn rate window<br/>短期 window のみ設定]
Q2 -->|コストが予算超え| T7[詰まり7: コスト見積罠<br/>複合料金計算漏れ]
Q3 -->|ノード爆発 / 依存関係不明| T3[詰まり3: Service Map noise<br/>低頻度サービス過多]
Q3 -->|Cross-account で表示されない| T5[詰まり5: Multi-account 集約失敗<br/>IAMポリシー設定漏れ]
Q4 -->|本番 CPU/メモリ影響大| T4[詰まり4: CodeGuru overhead<br/>Agent 本番影響過大]
Q4 -->|デプロイ後 Flame Graph が歪む| T6[詰まり6: Profile diff 誤判定<br/>ウォームアップ期間混入]
T1 --> FIX1[✅ p99: 99.9% → 99.5% に緩和<br/>Error budget 30日 = 43.2分確保]
T2 --> FIX2[✅ 1h:14.4x + 6h:6x 二段構成<br/>Short + Long window 組み合わせ]
T3 --> FIX3[✅ threshold_latency_ms 設定で<br/>低頻度サービスをフィルタ除去]
T4 --> FIX4[✅ sampling_interval=5s に調整<br/>Agent overhead を 1% 未満に]
T5 --> FIX5[✅ 送信側 AWSObservabilityAccess<br/>受信側 CloudWatchCrossAccount 追加]
T6 --> FIX6[✅ デプロイ後 30分は比較から除外<br/>Baseline 保存ポリシーを設定]
T7 --> FIX7[✅ AppSignals + SLO + Profiler 合計試算<br/>Pricing Calculator で事前計算]
詰まり1: SLO目標値を高く設定しすぎてError budgetが枯渇
症状
SLO を Availability 99.99% / p99 Latency < 100ms で設定したところ、毎月 10 日前後で Error budget が枯渇し、残りの 20 日間はリリースが凍結された。リリース速度が当初比 70% 低下した。
根本原因
Availability 99.99% の月間許容ダウンタイムは約 4.4 分だ。一回のデプロイによる Cold Start や一時的なレイテンシ上昇だけで budget を使い切る。実態に合わない高水準の SLO は、開発速度と信頼性の両立を不可能にする。
解決策
まず現状のエラー率 / 遅延実績を 30 日分計測し、ユーザー体感に基づく SLO を設定する。B2B サービスは 99.9% (月間 43.2 分)、コンシューマー向けは 99.5% (月間 3.6 時間) が現実的な起点となる。
resource "aws_cloudwatch_service_level_objective" "api_availability" {
name = "api-availability-slo"
sli {
sli_metric {
metric_data_queries {
id= "availability"
expression = "100 * (1 - error_rate)"
}
}
comparison_operator = "GreaterThanOrEqualToThreshold"
threshold = 99.5
}
goal {
interval {
rolling_interval {
duration= 30
duration_unit = "DAY"
}
}
attainment_goal= 99.5
warning_threshold = 99.7
}
}
- 30日間の実績エラー率を計測してから SLO 目標値を決定する — 実績なき高水準 SLO は百害あって一利なし
- まず 99.5% (月間 3.6h の Error budget) から始め、3ヶ月連続達成後に 99.9% への引き上げを検討する
- Error budget が月間 80% 消費したら自動でリリース凍結フローを起動するアラームを設定する
- SLO 目標値は顧客 SLA より 0.1〜0.5% 低めに設定して安全バッファを確保する
詰まり2: Burn rate windowを短期のみ設定してアラート疲労が発生
症状
1時間ウィンドウ (14.4x burn rate) のみでアラートを設定したところ、週に 20 件以上の False Positive が発生した。オンコール担当がアラートを無視するようになり、本物の障害を見逃す寸前になった。
根本原因
1時間という短いウィンドウは瞬間的なスパイクに過剰反応する。短期ウィンドウのみでは Error budget の緩やかな消耗 (6時間で 6x burn rate) を見逃し、遅延した大規模障害の検知が遅れた。
解決策
Multi-window multi-burn-rate パターンを実装し、短期 + 長期の両方の閾値を通過した場合のみアラートを発報する。CloudWatch Composite Alarm を活用することで AND 条件を構成できる。
resource "aws_cloudwatch_composite_alarm" "slo_p1_critical" {
alarm_name = "slo-burn-rate-p1-critical"
alarm_rule = "ALARM(\"slo-1h-14x\") AND ALARM(\"slo-5m-14x\")"
alarm_actions = [var.pagerduty_sns_arn]
}
resource "aws_cloudwatch_composite_alarm" "slo_p2_warning" {
alarm_name = "slo-burn-rate-p2-warning"
alarm_rule = "ALARM(\"slo-6h-6x\") AND ALARM(\"slo-30m-6x\")"
alarm_actions = [var.slack_sns_arn]
}
- P1 (Critical): 1h:14.4x AND 5min:14.4x → PagerDuty 即時通知
- P2 (Warning): 6h:6x AND 30min:6x → Slack 通知のみ (対応は翌日でも可)
- P3 (Info): 3d:1x → 翌営業日対応チケットを自動作成
- 週あたりのアラート件数を 5 件以下に保つことを KPI として運用する
詰まり3: Service Map ノイズで依存関係が見えにくい
症状
本番環境に Application Signals を導入後、Service Map に 200 以上のノードが表示された。クリティカルな依存関係がノイズに埋もれ、障害時の原因調査に 40 分以上かかるようになった。
根本原因
ヘルスチェックエンドポイント・バッチジョブの定期呼び出し・内部メトリクス収集エージェントなど、低頻度かつ重要度の低いサービスが大量に auto-discovery されたことが原因だ。
解決策
exclude_links 設定と threshold_latency_ms による低頻度サービスのフィルタリングを適用する。環境ラベルを使って本番 Map のみを表示し、ノード数を 20〜30 以下に維持する。
{
"traces": {
"service_graph": {
"exclude_links": [
{"source": "health-check*"},
{"source": "metrics-collector*"},
{"destination": "internal-batch*"}
],
"threshold_latency_ms": 10,
"threshold_error_rate": 0.001
}
}
}
- ヘルスチェック・バッチ・内部エージェントを exclude_links で明示除外する
- threshold_latency_ms=10 で p99 10ms 未満の低重要度リンクを非表示にする
- Service Map のノード数を 20〜30 以下に保つことを目標にフィルタを調整する
- 重要なクリティカルパスのみ表示する「コア依存関係 Map」ビューを CloudWatch ダッシュボードに別途作成する
詰まり4: CodeGuru Profiler Agentの本番オーバーヘッドが予想を超えた
症状
CodeGuru Profiler Agent を本番の Java サービス (8 vCPU) に展開したところ、CPU 使用率が平均 +8% 上昇し p99 Latency が 15ms 悪化した。SLO の Latency 目標が達成できなくなった。
根本原因
デフォルトの sampling_interval が 1 秒と短く、高負荷時に Profiler 自体がボトルネックになっていた。また Heap サマリー収集を全エンドポイントで有効にしたため JVM の GC 圧力が増大した。
解決策
sampling_interval を 5 秒に設定し、Heap サマリーは重要サービスのみに限定する。Agent overhead の許容上限は CPU 1% 未満・Latency 1ms 未満を指標にして調整する。
// -Dcom.amazonaws.services.codeguruprofiler.samplingIntervalInMilliseconds=5000
// -Dcom.amazonaws.services.codeguruprofiler.heapSummaryEnabled=false
ProfilingGroup profilingGroup = ProfilingGroup.builder()
.profilingGroupName("production-api-service")
.build();
Profiler profiler = Profiler.builder()
.profilingGroup(profilingGroup)
.build();
profiler.start();
- ステージング環境で 24 時間計測し CPU / Latency の増加量を事前把握してから本番展開する
- sampling_interval=5000ms (5秒) を基準値とし overhead が 1% 超なら 10000ms (10秒) に延長する
- Heap Summary は初期は無効化し Hot path 特定後に必要なエンドポイントのみ有効にする
- 本番展開時は SLO の Latency 閾値を 10% 一時緩和してウォームアップバッファを確保する
詰まり5: Multi-account Service Map でクロスアカウント集約に失敗
症状
マルチアカウント構成 (本番 3 アカウント) で Service Map を有効化したが、中央監視アカウントから各アカウントのサービスが表示されず依存関係が途切れた状態になった。障害時に影響範囲の特定に 30 分以上かかった。
根本原因
各アカウントに cloudwatch:PutMetricData と xray:PutTraceSegments の Cross-account ポリシーは設定済みだったが、Application Signals 専用の AWSObservabilityAccess マネージドポリシーが未設定だった。
解決策
送信側アカウントに AWSObservabilityAccess をアタッチし、受信側 (監視アカウント) の Observability Access Manager に Source Account を登録する。
resource "aws_iam_role_policy_attachment" "observability_access" {
role = aws_iam_role.ecs_task_role.name
policy_arn = "arn:aws:iam::aws:policy/AWSObservabilityAccess"
}
resource "aws_oam_sink" "monitoring_account_sink" {
name = "production-monitoring-sink"
}
resource "aws_oam_link" "source_account_link" {
label_template = "$AccountName"
resource_types = ["AWS::CloudWatch::Metric", "AWS::Traces::TraceSegment"]
sink_identifier = aws_oam_sink.monitoring_account_sink.arn
tags = {
Environment = "production"
}
}
- 送信側アカウントの IAM Role に AWSObservabilityAccess マネージドポリシーを追加する
- 受信側 (監視アカウント) で Observability Access Manager の Sink を作成し Source Account を登録する
- 設定後 10 分以内に Service Map に各アカウントのサービスが表示されることを確認する
- Organizations 全体に適用する場合は SCP の Allow リストに AWSObservabilityAccess を追加する
詰まり6: デプロイ直後のウォームアップ期間でProfile diffが誤判定
症状
新バージョンのデプロイ後に CodeGuru Profiler で Flame Graph を比較したところ、JIT コンパイル前のコールドパスが Hot path として検出された。存在しないパフォーマンス劣化の調査に 2 時間を費やした。
根本原因
JVM の JIT コンパイル完了には 5〜30 分かかる。デプロイ直後の Profiler データには JIT 前の低速なインタープリタ実行が混入するため、比較ベースラインが汚染される。Lambda の場合はコールドスタートが同様の誤判定を引き起こす。
解決策
デプロイ後 30 分間のデータを比較対象から除外する。CI/CD パイプラインにウォームアップ待機ステップを追加し、JIT 完了後のみデータを取得してベースラインを更新する。
import boto3
from datetime import datetime, timezone, timedelta
import time
def update_baseline_after_warmup(profiling_group_name: str, warmup_min: int = 30) -> None:
warmup_end = datetime.now(timezone.utc) + timedelta(minutes=warmup_min)
print(f"Waiting for JIT warmup until {warmup_end.isoformat()}")
time.sleep(warmup_min * 60)
client = boto3.client("codeguruprofiler")
client.post_feedback(
profilingGroupName=profiling_group_name,
anomaly={"id": "latest"},
type="Positive"
)
print(f"Baseline updated after {warmup_min} min warmup period.")
- Blue/Green デプロイ時は Green トラフィック切り替えから 30 分後に Profiler 比較を開始する
- CI/CD パイプラインにウォームアップ待機ステップを追加し JIT 完了後のみデータ取得する
- Lambda の場合は Provisioned Concurrency を有効化してコールドスタートによる誤判定を排除する
- Baseline は週次更新とし緊急デプロイ後は翌営業日に手動レビューを実施するルールを設ける
詰まり7: Continuous Profiling の料金計算でコストが大幅超過
症状
CodeGuru Profiler と Application Signals を全サービス (20 マイクロサービス) に展開したところ、月次コストが試算の 4 倍になった。特に Continuous Profiling の CPU コア時間課金の計算を誤っていた。
根本原因
CodeGuru Profiler は「プロファイリング時間 (CPU コア × 時間)」で課金される。8 vCPU のサービスを 720 時間 (30 日) 動かすと 5,760 CPU コア時間になる。また Application Signals は API コール数とカスタムメトリクス数の両方で課金されることを見落としていた。
解決策
サービスごとに CPU コア数 × 稼働時間を事前試算し、高コアサービスは sampling_interval を延長してコストを抑制する。まず Top 5 サービスに限定して展開し効果測定後に段階的に拡大する。
CodeGuru Profiler コスト試算:
- 8 vCPU × 720h/月 = 5,760 CPU コア時間/月
- 料金: $0.005 / CPU コア時間
- コスト: 5,760 × $0.005 = $28.8/月 (1サービス)
- 全20サービスに展開: $28.8 × 20 = $576/月
コスト削減策:
- sampling_interval=10s → 課金対象 50% 削減 → $288/月
- 本番のみ有効化 (ステージング除外) → さらに約 30% 削減
- 重要上位 5 サービスのみに絞り込む → $28.8 × 5 = $144/月
Application Signals 追加コスト:
- 無料枠: 150万 API コール/月 + 10 カスタムメトリクス/月
- 超過: $0.35 / 1,000 API コール、$0.30 / メトリクス
- CodeGuru Profiler = CPU コア数 × プロファイリング時間 (h) × $0.005 で計算する
- Application Signals = API コール数 (150万/月無料) + カスタムメトリクス数 ($0.30/メトリクス) を別途計上する
- まず上位 5 サービス (トラフィック Top 5) のみ有効化し効果測定後に段階的に拡大する
- AWS Pricing Calculator で全サービスの合計コストを事前にシミュレーションしてから全体展開に進む
§7 アンチパターン → 正解パターン変換演習 (5問)
Application Signals × SLO/SLI × Service Map × CodeGuru Profiler の本番設計でよくある「アンチパターン」を「正解パターン」に変換する演習を5問用意した。各問でビフォー / アフターの Terraform コードを比較し、設計の落とし穴を体で覚えてほしい。
Q1: 手動CloudWatchダッシュボード → Application Signals 自動SLO
❌ アンチパターン — 手動ダッシュボードによる目視運用
複数のマイクロサービスに対して aws_cloudwatch_dashboard で手動メトリクスウィジェットを設定し、オンコール担当が目視で SLO 達成状況を確認していた。サービス数が増えるにつれダッシュボード管理コストが爆発し、SLO の定義もチームによってバラバラになった。
# ❌ アンチパターン: 手動 CloudWatch Dashboard + 目視確認
resource "aws_cloudwatch_dashboard" "manual_slo" {
dashboard_name = "service-health-manual"
dashboard_body = jsonencode({
widgets = [{
type = "metric"
properties = {
metrics = [["AWS/ApplicationELB", "HTTPCode_ELB_5XX_Count"]]
title= "5xx errors (手動確認)"
}
}]
})
}
✅ 正解パターン — Application Signals による SLO 自動化
aws_cloudwatch_service_level_objective で SLO を宣言的に定義する。auto-discovery により新サービスが自動で Service Map に追加され、Burn rate alarm が自動生成される。ダッシュボードの手動管理が不要になる。
resource "aws_cloudwatch_service_level_objective" "api_latency" {
name = "api-latency-p99-slo"
sli {
sli_metric {
metric_data_queries {
id= "latency_p99"
expression = "SELECT PERCENTILE(Duration, 99) FROM SCHEMA(\"AWS/ApplicationSignals\", Operation, Service)"
}
}
comparison_operator = "LessThanThreshold"
threshold = 200
}
goal {
interval {
rolling_interval {
duration= 30
duration_unit = "DAY"
}
}
attainment_goal= 99.9
warning_threshold = 99.95
}
}
変化のポイント
- 設定工数: ダッシュボード手動設定 → SLO リソース 1 件で全サービスをカバー
- 標準化: チームごとにバラバラだった SLO 定義が Terraform で一元管理される
- 自動アラーム: Burn rate alarm が SLO から自動生成され、アラーム設定の手動ミスがなくなる
Q2: Uptime%固定アラート → SLO + Multi-window multi-burn-rate管理
❌ アンチパターン — Uptime% の固定閾値アラート
aws_cloudwatch_metric_alarm で Uptime < 99% という固定閾値アラートを設定していた。月末に Uptime が 99.1% になっていても Error budget の消耗速度を把握できず、翌月の大規模障害を防げなかった。
# ❌ アンチパターン: 単純 Uptime% 閾値アラート
resource "aws_cloudwatch_metric_alarm" "uptime_simple" {
alarm_name = "uptime-simple-alarm"
comparison_operator = "LessThanThreshold"
threshold = 99.0
metric_name= "Availability"
namespace = "Custom/Uptime"
period = 3600
statistic = "Average"
}
✅ 正解パターン — Multi-window multi-burn-rate + Error budget 管理
1h:14.4x と 6h:6x の2段階 Composite Alarm に切り替える。P1 (Critical) は即時通知、P2 (Warning) は Slack 通知に分離することでアラート疲労を防ぎながら Error budget の急速消耗を検知できる。
resource "aws_cloudwatch_metric_alarm" "burn_rate_1h" {
alarm_name = "slo-burn-rate-1h-14x"
comparison_operator = "GreaterThanThreshold"
threshold = 14.4
metric_name= "BurnRate"
namespace = "AWS/ApplicationSignals"
period = 3600
statistic = "Maximum"
dimensions = {
SloName = "api-availability-slo"
}
}
resource "aws_cloudwatch_composite_alarm" "slo_critical" {
alarm_name = "slo-critical-multiwindow"
alarm_rule = "ALARM(\"slo-burn-rate-1h-14x\") AND ALARM(\"slo-burn-rate-5m-14x\")"
alarm_actions = [var.pagerduty_sns_arn]
}
変化のポイント
- 検知精度: Uptime% の瞬間値 → Error budget の消耗速度 (burn rate) で検知するため月末の大規模障害を月初に予見できる
- False Positive 削減: AND 条件により短期スパイクによる誤報を 90% 削減できる
- エスカレーション: Critical / Warning / Info の 3 段階アラートで対応優先度が明確化される
Q3: CPU単発プロファイル → CodeGuru Profiler Continuous Profiling
❌ アンチパターン — 本番障害時のみプロファイル手動取得
パフォーマンス問題が発生したときだけ jstack や async-profiler を手動実行していた。問題発生時の負荷状況を再現できず、Hot path の特定に 2〜3 日かかるケースが続発した。
# ❌ アンチパターン: 手動 jstack による単発プロファイル
# 問題: 問題発生時の状態を後から参照できない
# 問題: 複数インスタンス間の比較ができない
✅ 正解パターン — CodeGuru Profiler Continuous Profiling
CodeGuru Profiler Agent を常時有効化することで、問題発生直前後の Flame Graph データが自動保存される。デプロイ前後の差分 (Profile diff) で Hot path の変化を 5 分以内に特定できる。
resource "aws_codeguruprofiler_profiling_group" "api_service" {
name = "production-api-service"
compute_platform = "Default"
agent_orchestration_config {
profiling_enabled = true
}
tags = {
Environment = "production"
Service = "api"
}
}
変化のポイント
- 問題の遡及分析: 常時 Profiling により問題発生直前の Flame Graph を事後参照できる
- デプロイ差分: Profile diff でコードの変化に伴う Hot path の増減を Terraform デプロイ後に即確認できる
- コスト最適化の根拠: Hot path を特定することで CPU 削減の対象関数を証拠に基づいて選定できる
Q4: 単一アカウントService Map → Cross-account 組織全体 Service Map
❌ アンチパターン — アカウント単位のサイロ化した Service Map
各 AWS アカウントで独立して Application Signals を有効化していたため、マイクロサービス間のリクエストがアカウント境界を越えると Service Map でトレースが途切れた。根本原因の特定に 1 時間以上かかった。
# ❌ アンチパターン: 各アカウント独立運用 (Cross-account 設定なし)
# account A: CloudWatch Agent 設定済み (独立)
# account B: CloudWatch Agent 設定済み (独立)
# → Service Map が account ごとに分断される
✅ 正解パターン — OAM による統合 Service Map
CloudWatch OAM (Observability Access Manager) の Sink / Link を使って、複数アカウントのトレースデータを監視アカウントに集約する。全アカウントの依存関係を 1 つの Service Map で俯瞰できるようになる。
resource "aws_oam_sink" "central_monitoring" {
name = "central-observability-sink"
}
resource "aws_oam_sink_policy" "allow_source" {
sink_identifier = aws_oam_sink.central_monitoring.arn
policy = jsonencode({
Version = "2012-10-17"
Statement = [{
Effect = "Allow"
Principal = { AWS = var.source_account_ids }
Action = ["oam:CreateLink", "oam:UpdateLink"]
Resource = "*"
}]
})
}
resource "aws_oam_link" "to_central" {
label_template = "$AccountName"
resource_types = [
"AWS::CloudWatch::Metric",
"AWS::Traces::TraceSegment",
"AWS::ApplicationSignals::ServiceLevelObjective"
]
sink_identifier = var.central_monitoring_sink_arn
}
変化のポイント
- 可視性: Cross-account トレースが 1 つの Service Map で完結し障害の連鎖を即座に把握できる
- SLO 統合管理: 全アカウントの SLO 達成状況を監視アカウントから一元確認できる
- 導入工数: OAM Sink/Link の Terraform 設定は 1 アカウントあたり 30 分以内に完了する
Q5: アラートなし運用 → Multi-window multi-burn-rate アラート体系
❌ アンチパターン — 本番障害を顧客クレームで検知
メトリクス監視はあったが SLO に基づくアラートが未整備だった。本番で Error budget が枯渇していても検知できず、顧客からのクレームで初めて障害を把握するケースが月 2〜3 回発生していた。
# ❌ アンチパターン: CloudWatch Alarm はあるが SLO Burn rate 未設定
resource "aws_cloudwatch_metric_alarm" "error_rate" {
alarm_name = "high-error-rate"
comparison_operator = "GreaterThanThreshold"
threshold = 5.0
metric_name= "5xxErrorRate"
period = 300
statistic = "Average"
}
✅ 正解パターン — SLO ベースの完全なアラート体系
3 段階 (Critical/Warning/Info) の Multi-window multi-burn-rate アラート体系を構築する。顧客がクレームを上げる前に自律的に検知・エスカレーションできる体制が完成する。
locals {
burn_rate_alarms = {
"1h-14x" = { window = 3600,threshold = 14.4, severity = "critical" }
"5m-14x" = { window = 300, threshold = 14.4, severity = "critical" }
"6h-6x"= { window = 21600, threshold = 6.0, severity = "warning" }
"30m-6x" = { window = 1800,threshold = 6.0, severity = "warning" }
"3d-1x"= { window = 259200, threshold = 1.0, severity = "info" }
}
}
resource "aws_cloudwatch_metric_alarm" "burn_rate" {
for_each = local.burn_rate_alarms
alarm_name = "slo-burn-rate-${each.key}"
comparison_operator = "GreaterThanThreshold"
threshold = each.value.threshold
metric_name= "BurnRate"
namespace = "AWS/ApplicationSignals"
period = each.value.window
statistic = "Maximum"
}
変化のポイント
- 事前検知: Error budget の消耗速度を監視することで顧客影響前に検知できる
- 疲労軽減: AND 条件の Composite Alarm により False Positive を大幅に削減する
- 対応時間最適化: P1/P2/P3 の 3 段階で対応優先度が明確化され MTTR が短縮される
§8 まとめ + Observability三部作完成 + 50記事化大台達成 + 全軸クロスリンクナビ
8-1. 4本柱まとめ — Application Signals × SLO/SLI × Service Map × CodeGuru Profiler
本記事では AWS Observability Vol3 として、Vol1 (X-Ray / OTel 基礎) と Vol2 (CloudWatch Logs 縦深化) の基盤の上に構築される「SLO/Profile 層」の4サービスを体系的に解説した。
Application Signals 本番運用 — SLO自動定義の核心
Application Signals の核心は SLO の自動化だ。aws_cloudwatch_service_level_objective で Latency (p99) と Availability の SLO を宣言的に定義し、auto-discovery が ECS / EKS / Lambda / EC2 のサービスを自動検出して Service Map を構成する。手動ダッシュボード管理から SLO 宣言的定義への転換は、運用コストを劇的に削減する。SLO 初期設定は実績 30 日分の計測後に 99.5% から始め、3 ヶ月連続達成後に段階的に引き上げる方針が現実的だ。
SLO/SLI 管理 — Error budget と Burn rate の二本柱
SLO/SLI 管理の本番設計は Error budget の可視化と Multi-window multi-burn-rate アラートの二本柱で成立する。Error budget = 月間許容ダウンタイム (99.9% なら 43.2 分) は、リリース凍結トリガーや開発速度の調整指標になる。Burn rate は 1h:14.4x AND 5m:14.4x の P1 Critical と 6h:6x AND 30m:6x の P2 Warning で構成し、週あたりのアラート件数を 5 件以下に保つことを KPI にする。SLI は Availability / Latency / Throughput / Correctness の 4 軸を用途に応じて選択し、Composite Alarm で段階エスカレーションを構成する。
Service Map 本番運用 — 依存関係の可視化設計
Service Map の価値は依存関係の可視化と障害の連鎖追跡だ。マルチアカウント環境では OAM (Observability Access Manager) の Sink/Link と AWSObservabilityAccess ポリシーの組み合わせで全アカウントの Service Map を統合できる。ノイズ制御には exclude_links と threshold_latency_ms を活用し、Service Map のノード数を 20〜30 以下に保つことで障害時の Root Cause Analysis を 5 分以内に完了できる設計を目指す。
CodeGuru Profiler 本番運用 — Continuous Profiling で Hot path を可視化
CodeGuru Profiler の最大の強みは Continuous Profiling による問題の事後遡及だ。手動の jstack や単発プロファイルでは捉えられなかった本番の Hot path を、Flame Graph と Call tree で継続的に記録できる。Agent overhead は sampling_interval=5000ms を起点として CPU 1% 未満に調整する。Profile diff でデプロイ前後の Hot path 変化を追跡し、コスト最適化の対象関数を根拠に基づいて選定することで、エンジニアリング投資対効果が最大化される。
本番導入チェックリスト — Observability Vol3 全4サービス
| カテゴリ | チェック項目 | 合否基準 |
|---|---|---|
| Application Signals | SLO 目標値 | 30日実績ベースで 99.5% から設定済み |
| Application Signals | Burn rate alarm | Multi-window AND 条件で構成済み |
| Application Signals | auto-discovery | ECS/EKS/Lambda タスクロールに AWSObservabilityAccess 付与済み |
| SLO/SLI | Error budget | 月間許容ダウンタイムを計算し 80% 消費時の自動通知設定済み |
| SLO/SLI | 段階エスカレーション | P1/P2/P3 の 3 段階アラート構成済み |
| Service Map | ノード数 | exclude_links / threshold でフィルタし 30 以下 |
| Service Map | Cross-account | OAM Sink/Link + AWSObservabilityAccess 設定済み |
| CodeGuru Profiler | overhead | sampling_interval 調整で CPU 1% 未満確認済み |
| CodeGuru Profiler | Baseline 更新 | デプロイ後 30 分ウォームアップ後に更新ルール設定済み |
| コスト | 合計試算 | AppSignals + SLO + Profiler の月間コストを事前計算済み |
以上のチェックリストを全項目クリアしてから本番展開に進むことで、Observability Vol3 の4サービスを安全に導入できる。
§6 詰まり7選の対処法と §7 演習5問も合わせて参照し、設計判断の根拠を固めてほしい。特に詰まり1 (SLO 目標値) と詰まり2 (Burn rate window) は導入初期に最も多くのチームが踏むパターンだ。
8-2. Observability三部作完成 + Vol1↔Vol2↔Vol3 完全ナビ
Vol1 (X-Ray / OpenTelemetry / Application Signals / ADOT 基礎運用) → Vol2 (CloudWatch Logs 縦深化 / Logs Insights / Centralized Logging / コスト最適化) → Vol3 (SLO/Profile 層 / Application Signals 本格 / SLO/SLI / Service Map / CodeGuru Profiler) の三部作が、ここに完結した。
Observability 三部作は「下層から上層へ」の構造で設計されている。Vol1 は分散トレースの基礎 (X-Ray / OTel) と Application Signals の初期設定を担当した。Vol2 は CloudWatch Logs の縦深化 (Logs Insights クエリ / Lambda Logs 統合 / Centralized Logging / コスト最適化) を担当した。本 Vol3 は SLO の本格運用と Continuous Profiling という「観測から制御へ」の上位層を担当した。
Vol1 (基礎運用層) — X-Ray / OpenTelemetry / Application Signals / ADOT
分散トレースの基礎を構築する。X-Ray によるリクエスト追跡、OpenTelemetry による標準計装、Application Signals の初期設定、ADOT による OpenTelemetry コレクターの本番展開が主要テーマだ。Vol1 を完了すると「トレースが通る」基盤が整う。
Vol2 (ログ縦深化層) — CloudWatch Logs / Logs Insights / Centralized Logging
Logs Insights のクエリ最適化、Lambda Log Group の統合管理、Organization レベルの Centralized Logging、コスト最適化 (Log Group 保持期間 / Insights Contributor / S3 Export) が主要テーマだ。Vol2 を完了すると「ログが見える」基盤が整う。
Vol3 (SLO/Profile 層) — 本記事 — Application Signals 本格 / SLO/SLI / Service Map / CodeGuru Profiler
SLO 自動定義 / Error budget 管理 / Multi-window multi-burn-rate / Service Map 組織統合 / Continuous Profiling が主要テーマだ。Vol3 を完了すると「観測から制御へ」の完全な SRE 基盤が整う。
三部作の読み方: Vol1 → Vol2 → Vol3 の順に読み進めることが推奨だが、既に X-Ray と Logs 基盤が整備されているチームは直接 Vol3 から始めることも有効だ。SLO 管理が未整備であれば §3 (SLO/SLI 管理) から入る。依存関係の可視化が課題であれば §4 (Service Map) が最短ルートだ。Continuous Profiling が目的なら §5 (CodeGuru Profiler) に直接進んでほしい。
三部作で得た知識は SRE (Site Reliability Engineering) の実践基盤となる。Error budget 管理と Burn rate アラートによる「Reliability vs. Velocity のバランス制御」は、SRE の核心概念だ。三部作を通じて AWS の Observability 技術スタックを縦断的に習得したエンジニアは、本番システムの信頼性を定量的に管理できるようになる。
Observability 三部作は Vol1 → Vol2 → Vol3 で論理的に完結しているが、SRE の旅に終わりはない。今後も新サービスの登場や運用パターンの進化に合わせて各 Vol を更新していく予定だ。三部作の完成を祝うとともに、次の縦深化軸にも期待してほしい。
三部作で完成する SRE の観測サイクル
Observability の実践は「収集 → 検知 → 分析 → 改善」の4サイクルで回る。三部作はこのサイクルの各層を担当している。
| サイクル | 担当 Vol | 主要ツール |
|———|———|———–|
| 収集 (Collect) | Vol1 X-Ray/OTel | ADOT SDK / CloudWatch Agent / X-Ray Daemon |
| 蓄積 (Store) | Vol2 Logs | CloudWatch Logs / S3 Export / Centralized |
| 検知 (Detect) | Vol2+Vol3 SLO | CloudWatch Alarms / Burn rate / Logs Insights |
| 分析 (Analyze) | Vol1+Vol2+Vol3 | Service Map / X-Ray Trace / Flame Graph |
| 改善 (Improve) | Vol3 Profiler/SLO | Profile diff / Error budget / Cost optimization |
Vol1 で収集基盤を整備し、Vol2 でログ分析を深化させ、Vol3 で SLO 管理と Continuous Profiling を導入することで、この5ステップがすべて自動化される。このサイクルが回り始めると、本番障害への対応が「発見→調査→修正→検証」から「予測→予防→計測→改善」に変わる。
Observability 三部作を完成させたチームは、顧客からクレームを受ける前に問題を検知し、データに基づいてシステムを改善し続ける SRE 組織へと進化する。Error budget が尽きれば自動でリリースを凍結し、Flame Graph が劣化を示せばホットパスを特定して最適化し、Service Map が依存関係の変化を検知すればアーキテクチャ判断に活用する — それが三部作が目指した最終到達点だ。
三部作は今後も進化する。新しい AWS サービスの登場に合わせて各 Vol を更新し、読者が常に最新の本番運用パターンを参照できる状態を維持していく。本シリーズへのフィードバックや気づきがあれば、コメント欄でぜひ共有してほしい。
三部作 学習達成度チェックリスト
三部作を通じて以下の4つの能力が身につく。すべてをチェックできたとき、SRE として次のレベルに到達している。
| 能力 | 内容 | 確認方法 |
|——|——|———|
| SLO 設計 | Error budget を計算し burn rate を設定できる | §3 演習を完遂 |
| Service Map 管理 | ノイズフィルタと Cross-account を設定できる | §4 Terraform を適用 |
| Continuous Profiling | Hot path を特定しコストを削減できる | §5 Profiler を 1 週間運用 |
| アラート体系 | P1/P2/P3 の 3 段階アラートを構成できる | §7 Q2/Q5 演習を完遂 |
三部作を完読したエンジニアへの推奨アクションをまとめる。まず Application Signals の SLO を 1 サービスに適用し、7 日間 Burn rate の推移を観察する。次に Multi-window multi-burn-rate アラートを設定し、アラート件数を週 5 件以下に絞り込む。最後に CodeGuru Profiler を Top 1 サービスに展開し、Flame Graph で Hot path を 1 件以上特定する。この 3 ステップが Vol3 を「知識」から「実践」に変える最短ルートだ。
AWS Observability の技術は進化が速い。Application Signals の機能拡張、CodeGuru Profiler の新言語サポート追加、OpenTelemetry 仕様の更新など、この技術領域は活発に進化し続けている。最新情報は各サービスの公式ドキュメントおよび AWS Blog を定期的に確認してほしい。本シリーズの記事も定期的にアップデートしていく。
Observability Vol1 — X-Ray × OpenTelemetry × Application Signals × ADOT 基礎運用
Observability Vol2 — CloudWatch Logs深掘り (Insights × Centralized × コスト最適化)
8-3. AWS本番運用シリーズ 50記事化大台達成 + 全軸全容
本 Observability Vol3 の公開により、AWS 本番運用シリーズは記念すべき 50 記事大台に到達した。49 記事 (IoT Vol2 公開) から今回の 50 記事へ — この節目は、シリーズ開始以来の積み上げが実を結んだ瞬間だ。50 記事という数字は単なる量的達成ではない。20 軸にわたり各 Vol を縦深化し、SRE・DevOps・AI/ML・IoT・Container・Security などの全領域を本番運用視点で体系的に網羅した質的達成だ。
AWS 本番運用シリーズ 全 20 軸の現況は以下の通り。
| 軸 | テーマ | Vol 数 |
|—-|——–|——–|
| 第1軸 | Compute (EC2 / Auto Scaling / ELB) | Vol1-2 |
| 第2軸 | Storage (S3 / EBS / EFS / FSx) | Vol1-2 |
| 第3軸 | Database (RDS / Aurora / DynamoDB / ElastiCache) | Vol1-4 |
| 第4軸 | Network (VPC / Direct Connect / Transit Gateway) | Vol1-2 |
| 第5軸 | Security (IAM / WAF / Shield / KMS) | Vol1-3 |
| 第6軸 | Container (ECS / EKS / Fargate) | Vol1-3 |
| 第7軸 | Serverless (Lambda / API Gateway / EventBridge) | Vol1-2 |
| 第8軸 | DevOps CI/CD (CodePipeline / CodeBuild / CodeDeploy) | Vol1-4 |
| 第9軸 | Observability (CloudWatch / X-Ray / OpenTelemetry) | Vol1-3 |
| 第10軸 | Analytics (Glue / Athena / EMR / Redshift) | Vol1 |
| 第11軸 | AI/ML (SageMaker / Bedrock / Rekognition / Comprehend) | Vol1-3 |
| 第12軸 | Edge/CDN (CloudFront / Route53 / Global Accelerator) | Vol1 |
| 第13軸 | Migration (DMS / MGN / DataSync) | Vol1 |
| 第14軸 | Hybrid (Outposts / ECS Anywhere / Hybrid 管理) | Vol1 |
| 第15軸 | IAM Advanced (SCP / Permission Boundary / ABAC) | Vol1 |
| 第16軸 | Step Functions (SF Distributed Map / Express / SDK) | Vol1-3 |
| 第17軸 | DevOps Platform (CDK Pipelines / GitOps / Karpenter) | Vol1-3 |
| 第18軸 | Game/Media (AppStream / MediaConvert / MediaLive / GameLift) | Vol1 |
| 第19軸 | IoT (Core / Greengrass / SiteWise / Events / Analytics / TwinMaker / FleetWise) | Vol1-2 |
| 第20軸 | (次期公開予定) | — |
全 20 軸 · 50 記事を体系的に読み進めることで、AWS 本番運用のすべての主要サービス領域を網羅できる。各記事は「§2〜§5 本番運用パターン → §6 詰まり7選 → §7 演習5問 → §8 まとめ」の統一構成で、担当領域の深掘りにも全体俯瞰にも使える設計になっている。
50 記事の読み方のすすめ: シリーズ全体を通読する必要はない。自分が担当するサービス領域の軸を選んで深掘りし、隣接軸 (例: Observability × DevOps、Container × AI/ML) を読んでクロスサービスの連携ポイントを押さえることが最も効率的だ。
50 記事という節目を達成できたのは、AWS 本番運用の課題に向き合い続けるエンジニアコミュニティがあってこそだ。今後も各軸の縦深化 Vol を追加し、SRE / Platform Engineering / FinOps などの新軸も投入していく。次の 100 記事に向けて、シリーズはさらに進化する。
シリーズ記事は定期的に最新 AWS サービス情報にアップデートされる。新しい Vol の公開通知を受け取りたい方はブックマークしておくことを推奨する。AWS 本番運用の 50 記事があなたの現場設計の羅針盤となることを願っている。
50 記事の活用ガイド — ロール別おすすめルート
SRE / インフラエンジニア: 第9軸 (Observability Vol1-3) → 第8軸 (DevOps Vol1-4) → 第6軸 (Container Vol1-3) の順が最も体系的だ。本番運用の3本柱 (CI/CD + Container + Observability) を習得できる。
バックエンドエンジニア: 第7軸 (Serverless) + 第3軸 (Database) + 第9軸 (Observability) の組み合わせが最も即効性が高い。Lambda × Aurora × X-Ray の連携パターンを中心に読み進めることを推奨する。
プラットフォームエンジニア: 第17軸 (DevOps Platform) + 第15軸 (IAM Advanced) + 第16軸 (Step Functions) を起点に全軸を俯瞰する読み方が効果的だ。CDK Pipelines と Organization 管理の連携がプラットフォーム設計の核心となる。
AI/ML エンジニア: 第11軸 (AI/ML Vol1-3) + 第9軸 (Observability) + 第3軸 (Database) が必読だ。SageMaker Model Monitor と Application Signals の連携、Feature Store と DynamoDB の活用パターンが設計力を向上させる。
50 記事という節目を超えた今、次なる目標は「全 20 軸を自在に横断できる AWS 本番設計力」だ。各軸の知識が連携することで、単一サービスの深掘りを超えた全体最適のアーキテクチャ設計が可能になる。
AWS 本番運用シリーズは「本番環境で実際に使える知識」にこだわり続けてきた。理論だけでなく Terraform コード・設定例・詰まり7選・演習5問という実践的な構成で、現場のエンジニアが今日から使える知識を提供することを一貫した方針としている。
50 記事を積み上げた今、シリーズは第2フェーズに入る。既存軸の縦深化 Vol の追加に加え、SRE / FinOps / Platform Engineering など新しい視点の軸も検討中だ。次の 50 記事も、現場エンジニアの設計力を底上げする内容を届けていく。
シリーズの発展は読者とともにある。気になる軸・追加してほしいテーマがあれば、記事のコメント欄でフィードバックを送ってほしい。50 記事大台を共に達成してくれたすべての読者に感謝する。
50 記事到達にあたり、シリーズを支えてきた技術的柱を振り返っておく。AWS マネージドサービスの進化 (Application Signals / Amazon Bedrock / Karpenter / CDK Pipelines など) に追随しながら、常に「本番で使えるか」という一点を判断基準にコンテンツを絞り込んできた。その結果が 20 軸 × 50 記事という体系的なナレッジベースとして結実した。
今後のシリーズ拡張において最も注目すべき方向性は、軸間の「連携パターン集」だ。例えば Observability × Container × DevOps の三軸を統合した「Platform Engineering の Observability 基盤設計」や、AI/ML × Serverless × Database を束ねた「生成 AI アプリのバックエンド設計」といった横断的コンテンツを充実させていく予定だ。
AWS 本番運用シリーズ 50 記事は、個人のキャリア開発にも組織のオンボーディングにも活用できる。新メンバーが担当サービス領域の軸から読み始め、ベテランがクロスサービス連携の軸を横断することで、チーム全体の AWS 本番設計力を底上げするリソースとして機能する。
8-4. Observability三部作マップ + 全軸接続図 (Mermaid02)
graph LR
OBS3[Observability Vol3<br/>SLO/Profile 層<br/>App Signals本格×SLO×Service Map×CodeGuru]
OBS1[Observability Vol1<br/>X-Ray/OTel 基礎]
OBS2[Observability Vol2<br/>CloudWatch Logs 縦深化]
OBS1 -->|上位層へ| OBS2
OBS2 -->|SLO/Profile 層へ| OBS3
OBS3 -.->|Container Insights 連携| CON[Container Vol1-3<br/>ECS/EKS/Fargate]
OBS3 -.->|SageMaker Model Monitor 連携| AI[AI/ML Vol1-3<br/>SageMaker/Bedrock]
OBS3 -.->|Performance Insights 統合| DB[Database Vol1-4<br/>RDS/Aurora/DynamoDB]
OBS3 -.->|CDK Pipelines SLO 計装| DEV[DevOps Vol1-3<br/>CodePipeline/CDK]
OBS3 -.->|Lambda Insights 統合| SRV[Serverless Vol1-2<br/>Lambda/EventBridge]
OBS3 -.->|Cross-region X-Ray| NET[Network Vol1-2<br/>VPC/Direct Connect]
OBS3 -.->|OAM Cross-account| IAM[IAM Advanced Vol1<br/>SCP/ABAC]
OBS3 -.->|IoT Events アラート統合| IOT[IoT Vol1-2<br/>Core/Greengrass/Events]
OBS3 -.->|SF Execution 監視| SF[Step Functions Vol1-3<br/>Distributed Map/Express]
OBS3 -.->|Storage コスト監視| STG[Storage Vol1-2<br/>S3/EBS/EFS]
Observability Vol3 は三部作の頂点として、他の全軸との接続点が最も多い。Container (EKS Container Insights) / AI/ML (SageMaker Model Monitor) / Database (Performance Insights) はそれぞれ Application Signals や CloudWatch と深く連携する。DevOps Vol1-3 の CI/CD パイプラインでは SLO を計装した Blue/Green デプロイが本番グレードの品質ゲートとなる。
Observability 三部作で築いたトレース → ログ → SLO/Profile の縦断基盤は、すべての軸の「観測可能性」を底上げする。IoT のデバイスデータから AI/ML の推論結果まで、あらゆる本番システムは Observability なしには信頼性を保証できない。三部作を基盤として、各軸の縦深化を進めてほしい。
8-5. 関連記事 ep-btn + 次のステップ
Observability Vol3 で習得した SLO / Error budget / Service Map / Continuous Profiling の知識は、他の軸と組み合わせることでさらに強力になる。以下の関連記事でクロスサービスの連携パターンを深めてほしい。
Observability Vol1 — X-Ray × OpenTelemetry × Application Signals × ADOT 基礎運用
Observability Vol2 — CloudWatch Logs深掘り (Insights × Centralized × コスト最適化)
Container Vol3 — EKS Pod Identity × Karpenter × Service Connect 本番設計
Observability Vol3 で得た SLO 設計の思想は、すべての本番サービスに適用できる普遍的な原則だ。まず §3 で解説した Multi-window multi-burn-rate のアラート体系を、自分のサービスの CloudWatch に実装してみることを強く推奨する。1 週間でアラート疲労が大幅に削減され、本番の健全性が数値で把握できるようになる。
次に §5 の CodeGuru Profiler を本番の 1 サービスに試験展開してほしい。Continuous Profiling の Flame Graph を 1 週間観察するだけで、これまで気づかなかった Hot path が必ず見つかる。その Hot path の最適化が CPU コスト削減と Latency 改善につながり、SLO の達成率が向上するという好循環が生まれる。
Observability Vol3 本番化アクションプラン
本記事を読み終えた SRE / Observability 担当エンジニアへ、具体的な次のアクションを提案する。
- Week 1: Application Signals SLO を 1 サービスに設定し、現状の Burn rate を 7 日間観察する
- Week 2: Multi-window multi-burn-rate アラートを本番に適用し、False Positive の件数を計測する
- Week 3: OAM Cross-account Service Map を有効化し、マルチアカウント依存関係を可視化する
- Week 4: CodeGuru Profiler を Top 1 サービスに展開し、Flame Graph で Hot path を 1 件以上特定する
4 週間のアクションプランを完走すると、Observability Vol3 の理論が実践として身につく。SLO 管理と Continuous Profiling の組み合わせによる「観測から制御へ」のサイクルを現場で回せるようになる。
AWS 本番運用シリーズ 50 記事化大台を達成した今、次の課題は「それをどう使うか」だ。本シリーズで得た知識を現場に持ち帰り、チームの設計力を底上げするエンジニアが一人でも増えることを願っている。
Observability Vol3 まで読み切ったエンジニアへ伝えたいことがある。三部作で解説した技術は、最初から全部を同時に導入する必要はない。スモールスタートで始め、価値を確認しながら段階的に拡大することを推奨する。
推奨導入順序:
① まず Application Signals を 1 サービスに有効化し、Service Map の auto-discovery を体験する。既に X-Ray が設定済みなら、ADOT SDK のバージョンアップだけで Application Signals が有効化される。
② 次に SLO を定義し、Burn rate の推移を 1 ヶ月観察する。手動ダッシュボードとの違いを体感したら、段階的に他のサービスにも SLO を広げる。
③ Multi-window multi-burn-rate アラートを本番に適用し、False Positive が削減されることを確認する。アラート件数を週 5 件以下に絞り込めたら、オンコール体制の品質が劇的に向上する。
④ 最後に CodeGuru Profiler を Top 1 サービスに展開し、Continuous Profiling の効果を測定する。Hot path を 1 件最適化できたら、Profiler の ROI が確認できる。
Observability 三部作を完読し実践したエンジニアは、AWS 本番システムの信頼性を定量的に管理できる SRE の基礎を手に入れた。この知識を活かして、現場のシステムを次のレベルへ引き上げてほしい。