- 1 1. なぜObservability実践か — 全7軸からの架橋 + AWS本番運用第8軸結節点
- 2 2. Observability 3本柱整理 — メトリクス / トレース / ログ + AWSサービスマップ
- 3 3. Application Signals実践 (山場1) — SLI / SLO / エラーバジェット / Service map / Burn rate alarm
- 4 4. X-Ray分散トレーシング実践 (山場2) — Service map / Sampling Rules / Trace analytics / Trace ID伝搬
- 5 5. CloudWatch + ADOT + OpenTelemetry 統合 — EKS Vol2発展
- 6 6. 詰まりポイント7選 図解
- 6.1 詰まりポイント 1: Application Signals 未有効化 — サービスマップに表示されない
- 6.2 詰まりポイント 2: サンプリングレート設定ミス — X-Ray コスト爆発とデータ欠損
- 6.3 詰まりポイント 3: SLO Burn Rate アラーム誤設定 — Fast Burn と Slow Burn の混同
- 6.4 詰まりポイント 4: ADOT Collector メモリ不足 — OOM でトレースが欠損
- 6.5 詰まりポイント 5: OpenTelemetry SDK バージョン不整合 — Collector との互換性問題
- 6.6 詰まりポイント 6: Cross-Account CloudWatch Metrics 権限設定漏れ
- 6.7 詰まりポイント 7: X-Ray Service Map のサービス名重複 — 同一名の複数サービスが混在
- 7 7. アンチパターン→正解パターン変換演習 (Terraform + ADOT yaml + OpenTelemetry SDK 3形式)
- 7.1 演習1 (Terraform): SLO 設定ミス — attainment_goal と sli_metric の不整合
- 7.2 演習2 (YAML): X-Ray サンプリングルール — 全トレース収集でコスト爆発
- 7.3 演習3 (Terraform): ADOT Collector — memory_limiter 未設定で OOM
- 7.4 演習4 (Python SDK): OpenTelemetry Tracer — span を close せず親子関係が壊れる
- 7.5 演習5 (Terraform): IAM ロール — xray:GetSamplingRules 権限漏れでサンプリングルール取得失敗
- 8 8. まとめ + Vol2予告 + 落とし穴10選 + 全7軸クロスリンク + 第8軸結節点完結宣言
1. なぜObservability実践か — 全7軸からの架橋 + AWS本番運用第8軸結節点
- Observability実践 Vol1 (本記事): Application Signals × SLO × X-Ray ← 第8軸結節点
- Observability実践 Vol2 (近日公開予告)
IAM入門4巻: Vol1 / Vol2 / Vol3 / Vol4
EKS本番運用3巻: Vol1 / Vol2 (本Vol1の前身) / Vol3
復旧・運用編4巻: Vol1 / Vol2 / Vol3 / Vol4
AIシリーズ Vol1: Bedrock Agents 本番運用
セキュリティ本格運用 Vol1: Security Hub × GuardDuty × Audit Manager
コスト最適化 Vol1: Cost Explorer × Budgets × Compute Optimizer
マルチアカウント運用 Vol1: Organizations × Control Tower × Landing Zone
1-1. なぜObservability実践が必要か — ブラックボックス化の壁と3つのリスク
AWS本番運用の7軸 (IAM/EKS/復旧/AI/セキュリティ/コスト最適化/マルチアカウント) を整備した環境でも、「何が起きているか見えない」状態では本番基盤の品質を保証できません。Observabilityとはシステムの内部状態を外部から観測可能にする設計哲学であり、本番運用において「問題が起きてから対処する」から「問題が起きる前に検知する」への転換を実現します。
Observability 3本柱 — メトリクス/トレース/ログ
Observabilityを構成する3本柱はそれぞれ異なる問いに答えます。
| シグナル | 問いかけ | 代表AWSサービス |
|---|---|---|
| メトリクス | 「今どんな状態か」を数値で把握 | CloudWatch Metrics / Application Signals |
| トレース | 「どこで時間がかかっているか」を追跡 | AWS X-Ray / ADOT |
| ログ | 「何が起きたか」を記録で確認 | CloudWatch Logs / Logs Insights |
3本柱は単独より組み合わせることで真価を発揮します。「メトリクスでSLO違反を検知 → トレースで遅延箇所を特定 → ログで詳細を確認」というフローが、MTTD (Mean Time To Detect) と MTTR (Mean Time To Recover) を劇的に短縮します。
ブラックボックス化の3つのリスク
リスク1: 根本原因特定の遅延
CPUやメモリ使用率の監視だけでは、「レイテンシが増加している」という事実はわかっても「どのコンポーネントのどの処理が原因か」を特定できません。マイクロサービス・ECS・Lambda・RDS・ElastiCache が連携する本番環境では、障害箇所の特定に数時間かかることが珍しくありません。X-Ray の分散トレーシングがなければ、サービス間の依存関係を人力でトレースする作業が発生します。
【根本原因特定の所要時間 比較】
従来監視 (CloudWatch メトリクスのみ):
・症状把握: 5分
・コンポーネント絞り込み: 30-60分 (ログを人力検索)
・根本原因特定: 1-3時間
・合計: 1.5-4時間
Observability基盤 (X-Ray + Application Signals + Logs):
・症状把握: 1分 (SLO Burn Rate アラート)
・コンポーネント絞り込み: 3分 (Service Map で可視化)
・根本原因特定: 5-15分 (Trace で直接特定)
・合計: 10-20分
リスク2: SLO未達とエラーバジェット枯渇
SLO (Service Level Objective) を定義していない環境では、「今月のシステム品質が目標を達成しているか」を客観的に評価できません。Application Signals は SLI (Service Level Indicator) を自動収集し、エラーバジェットの消費状況をリアルタイムに可視化します。エラーバジェットが枯渇しかけている状態でデプロイを強行すると、ユーザー影響が発生する確率が急上昇します。
【SLO管理なし vs あり の比較】
SLO管理なし:
・可用性の実態: 月次で手動集計 (翌月初に判明)
・デプロイ判断: 担当者の経験と勘
・障害後レビュー: 「なぜ止まったか」の議論に集中
SLO管理あり (Application Signals):
・可用性の実態: リアルタイム可視化 (エラーバジェット残量 %)
・デプロイ判断: エラーバジェット残量を基準に客観判断
・障害後レビュー: 「次にどう防ぐか」の議論に集中
リスク3: コスト最適化との連動不足
Observabilityデータなしにはコスト最適化の効果測定ができません。Compute Optimizer が「インスタンスを縮小せよ」と推奨しても、レイテンシへの影響を CloudWatch メトリクスで事前に検証しなければ安全に実施できません。メトリクス・トレース・ログの3本柱が揃うことで、コスト削減施策の「実施前/実施後」を定量比較できます。
1-2. 全7軸からの架橋 — 第8軸の位置付け
Observabilityは独立したシリーズではなく、これまでの7軸すべてに観測の目を向ける横断的な基盤です。7軸で「作った」インフラを「見える化」するのが第8軸の役割です。観測なき本番運用は、計器を持たないパイロットが夜間飛行をするのと同じリスクを抱えます。
EKS本番運用Vol2: FluentBit/ADOT/Container Insights → 本記事はEKS Vol2で学んだコンテナ観測可能性をEKS以外の全AWSサービスに拡張します。FluentBit によるログ収集・ADOT による OpenTelemetry 統合の知識がそのまま活用できます。
復旧・運用編4巻 → Chaos Engineering (復旧Vol2) で設計した実験の成功/失敗を SLO メトリクスで定量評価。SLO Burn Rate の急上昇を障害の early warning として活用します。
AIシリーズVol1 → Bedrock の API 呼び出しをX-Rayでトレース。レイテンシの高いモデル呼び出しを特定し、キャッシュ戦略やモデル選択の最適化に活用します。
セキュリティ本格運用Vol1 → CloudWatch Logs Insights によるセキュリティイベント分析。Audit ログ・アクセスログの構造化クエリで、セキュリティアラートと相関分析できます。
コスト最適化Vol1 → CloudWatch メトリクスの保存期間・解像度・カスタムメトリクス数がコストに直結。PutMetricData のコストを Observability 設計時に考慮します。
マルチアカウント運用Vol1 → Cross-Account CloudWatch メトリクス共有・Organizations Trail による全アカウントログ集約。マルチアカウント Observability の統合ビューを実現します。
IAM入門4巻 → CloudWatch Logs・X-Ray へのアクセス制御。IRSA による EKS ワークロードからの メトリクス送信権限設計が基礎になります。
【第8軸 Observability実践 — 全7軸の観測目】
IAM設計 ────→ CloudWatch/X-Ray アクセス制御
EKS設計 ────→ Container Insights / ADOT 拡張
復旧設計 ───→ SLO × Chaos Engineering 効果測定
AI設計 ─────→ Bedrock API トレーシング
セキュリティ→ ログ相関分析 / Audit Trail
コスト最適化→ メトリクスコスト管理
マルチアカウント→ Cross-Account Observability
↓ すべてを観測する基盤
Application Signals × SLO × X-Ray
1-3. 本記事の到達ゴール5点
本記事を読了し実装を進めることで、以下5点を習得できます。
ゴール1: Observability 3本柱 (メトリクス/トレース/ログ) を体系的に理解できる
CloudWatch メトリクス・X-Ray トレース・CloudWatch Logs の役割分担と連携設計を理解し、AWSサービスマップに当てはめて設計できます。
ゴール2: Application Signals で SLI/SLO を設計・実装できる
Application Signals の自動計装・SLI メトリクスの定義・SLO と Burn Rate アラートの設定・エラーバジェットの管理を Terraform で実装できます。
ゴール3: X-Ray で分散トレーシングを構築できる
X-Ray SDK/ADOT の計装・Service Map の活用・サンプリングルールの設計・Trace Analytics による根本原因特定フローを実装できます。
ゴール4: ADOT + OpenTelemetry で統合観測基盤を構築できる
ADOT Collector のデプロイ・OpenTelemetry SDK の計装・マルチシグナル (メトリクス/トレース/ログ) の統合エクスポートを EKS/ECS/Lambda に対して実装できます。
ゴール5: 詰まりポイント7選 + 演習5問でアンチパターンを正解パターンに変換できる
X-Ray サンプリングの落とし穴・Application Signals の自動計装が効かないケース・CloudWatch Logs Insights のコストトラップなど、実装時に必ず直面する7つの詰まりポイントを先読みし、正しい実装パターンを選択できます。
章構成と学習マイルストーン
| 章 | タイトル | 習得スキル |
|---|---|---|
| §2 | Observability 3本柱整理 | メトリクス/トレース/ログの全体像 |
| §3 | Application Signals 実践 | SLI/SLO/エラーバジェット設計 |
| §4 | X-Ray 実践 | 分散トレーシング・Service Map |
| §5 | ADOT + OpenTelemetry | 統合観測基盤構築 |
| §6 | 詰まりポイント7選 | アンチパターン回避 |
| §7 | Terraform IaC 化 | 完全自動化 |
| §8 | まとめ | 全7軸との統合観測設計 |
本記事は第8軸の入口です。メトリクス単体の監視から、トレース・ログを統合した真のObservabilityへ。この質的転換が第8軸学習の核心です。§2のAWSサービスマップから実装に入りましょう。
Observabilityは一度構築して終わりではありません。
ワークロードの変化・新サービスの追加・SLO目標の見直しに合わせて継続的に改善します。
本記事で習得する3本柱のサイクル (計装 → 可視化 → 改善 → 再計装) が、AWS本番基盤の品質を長期的に支えます。
2. Observability 3本柱整理 — メトリクス / トレース / ログ + AWSサービスマップ
AWS の Observability は「メトリクス / トレース / ログ」の3本柱で体系化できます。3本柱をそれぞれ単独で運用しても根本原因特定は困難です。「メトリクスで異常を検知し、トレースで影響箇所を特定し、ログで原因を確認する」という3本柱の連携によって初めて効率的な問題解決が実現します。

2-1. Observability 3本柱の全体像
| 柱 | 問い | 強み | 代表 AWS サービス |
|---|---|---|---|
| メトリクス (Metrics) | 何が起きているか | 数値・集計・アラームで異常を即時検知 | CloudWatch Metrics / Application Signals SLI |
| トレース (Traces) | どこで詰まっているか | リクエスト追跡で分散システムのボトルネックを特定 | X-Ray / ADOT / Application Signals Service map |
| ログ (Logs) | なぜ起きているか | 詳細イベントでデバッグ・根本原因を確認 | CloudWatch Logs / Logs Insights |
Observability の成熟度モデルを理解することで、現状のギャップと次のアクションが明確になります。
| 成熟度 | 状態 | 導入済み要素 |
|---|---|---|
| Level 1 (基礎監視) | アップタイム監視のみ / アラートなし | CloudWatch 標準メトリクス |
| Level 2 (ログ管理) | ログ収集あり / 検索が困難 | + CloudWatch Logs |
| Level 3 (メトリクス管理) | カスタムメトリクス + アラーム | + カスタムメトリクス + Alarms |
| Level 4 (トレーシング) | 分散システムのボトルネック特定可 | + X-Ray / Application Signals |
| Level 5 (SLO駆動) | SLI/SLO/エラーバジェットで信頼性管理 | + Application Signals SLO + ADOT |
本記事の目標は Level 4〜5 の実装です。§3 (Application Signals) で SLO を、§4 (X-Ray) でトレーシングを構築します。
【Observability 3本柱 連携フロー】
① CloudWatch Alarm 発火 (メトリクス異常検知)
例: Latency P99 > 2000ms でアラーム
② X-Ray / Application Signals Service map で調査 (トレース)
例: Order Service → Payment Service 間で 1500ms のスパイク
③ CloudWatch Logs Insights で詳細確認 (ログ)
例: Payment Service のログに "DB connection timeout" が多発
④ 根本原因特定 → 対応
例: RDS 接続プールの枯渇 → パラメータチューニング
従来の監視との違い:
| 観点 | 従来の監視 (Monitoring) | Observability |
|---|---|---|
| 目的 | 既知の問題を検知する | 未知の問題を調査・解明する |
| アプローチ | ダッシュボード・アラートで状態確認 | メトリクス・トレース・ログを横断して根本原因を特定 |
| SLO との関係 | アップタイム (稼働率) 監視が中心 | SLI → SLO → エラーバジェットで信頼性を定量管理 |
| 分散システム対応 | 困難 (サービス境界で見えなくなる) | X-Ray / OpenTelemetry でサービス間を追跡可能 |
CloudWatch Metrics の基本構造
CloudWatch Metrics の理解には5つの概念が重要です。
| 概念 | 説明 | 例 |
|---|---|---|
| Namespace | メトリクスの論理グループ | AWS/EC2 / MyApp/Orders |
| Metric Name | 計測対象の名前 | CPUUtilization / OrderCount |
| Dimension | メトリクスを識別する属性 | InstanceId=i-xxx / Environment=production |
| Period | 集計時間単位 | 60秒 / 300秒 (5分) |
| Statistics | 集計方法 | Average / Sum / Maximum / p99 |
カスタムメトリクスの送信例 (Python):
import boto3
cw = boto3.client("cloudwatch", region_name="ap-northeast-1")
cw.put_metric_data(
Namespace="MyApp/Orders",
MetricData=[{
"MetricName": "ProcessingTimeMs",
"Value": 245.0,
"Unit": "Milliseconds",
"Dimensions": [
{"Name": "Environment", "Value": "production"},
{"Name": "Service", "Value": "order-service"}
]
}]
)
2-2. CloudWatch エコシステム概観
AWS の Observability 基盤は CloudWatch を中心に複数のサービスが連携します。
| サービス | 担当柱 | 主な機能 | 有効化優先度 |
|---|---|---|---|
| CloudWatch Metrics | メトリクス | AWS リソースのメトリクス収集 / カスタムメトリクス / アラーム | ★ 自動有効 |
| CloudWatch Logs | ログ | ログストリーム / Logs Insights / メトリクスフィルター | ★ 高 |
| CloudWatch Alarms | メトリクス | 閾値/異常検知/コンポジットアラームで通知・自動アクション | ★ 高 |
| Application Signals | メトリクス + トレース | SLI/SLO 自動計測 / Service Map / Burn rate アラーム | ○ 中 |
| X-Ray | トレース | 分散トレーシング / サービスマップ / レイテンシ分布 | ○ 中 |
| Container Insights | メトリクス + ログ | EKS/ECS 専用メトリクス/ログ収集 (EKS Vol2 発展) | ○ 中 |
| AWS Distro for OpenTelemetry (ADOT) | メトリクス + トレース + ログ | OpenTelemetry 準拠のデータ収集 / CloudWatch + X-Ray 送信 | ○ 中 |
Application Signals — SLI/SLO の自動計測
Application Signals は 2024 年に GA となった機能で、コードを変更せずに SLI (Service Level Indicator) を自動計測します。Availability (可用性) と Latency (レイテンシ) を標準 SLI として自動収集し、SLO 設定・エラーバジェット計算・Burn rate アラームまで一括設定できます。
【Application Signals SLO 設計例】
SLI: Availability = (成功リクエスト数) / (全リクエスト数)
SLO: 99.9% (30日間) = エラー許容 43.2 分/月
エラーバジェット: 100% - 99.9% = 0.1%
Burn rate アラーム:
Fast (1時間): Burn rate > 14.4x → 即時通知 (バジェット 1 時間で枯渇)
Slow (6時間): Burn rate > 6x → 警告通知 (バジェット 1 日で枯渇)
X-Ray — 分散トレーシングの基盤
X-Ray はマイクロサービス間のリクエストフローをTrace IDで追跡し、どのサービスがレイテンシを発生させているかを Service Map で可視化します。
サンプリングルールで収集量を制御し、コストを管理します。デフォルトは毎秒 1 リクエスト + 5% の固定レートですが、Production では重要パスのみ 100% 収集する設定が効果的です。
X-Ray の Trace ID はリクエストヘッダー (X-Amzn-Trace-Id) で伝搬されます。API Gateway → Lambda → RDS のような多段構成でも、単一の Trace ID でエンドツーエンドのレイテンシを追跡できます。
§4 では X-Ray のサンプリングルール設計・Service Map の読み方・Trace analytics を実践します。
ADOT — OpenTelemetry の AWS 実装
AWS Distro for OpenTelemetry (ADOT) は CNCF の OpenTelemetry 標準に準拠したコレクターです。アプリケーションに OpenTelemetry SDK を組み込むことで、CloudWatch Metrics / X-Ray Traces / CloudWatch Logs の3本柱すべてに単一のコレクターからデータを送信できます。
# ADOT Collector 設定例 (EKS サイドカー)
receivers:
otlp:
protocols:
grpc:
endpoint: 0.0.0.0:4317
exporters:
awsxray:
region: ap-northeast-1
awsemf:
namespace: MyApp
region: ap-northeast-1
log_group_name: /aws/myapp/metrics
service:
pipelines:
traces:
receivers: [otlp]
exporters: [awsxray]
metrics:
receivers: [otlp]
exporters: [awsemf]
Terraform で CloudWatch Alarm と Application Signals SLO を基本設定する例:
# CloudWatch Composite Alarm (複合アラーム)
resource "aws_cloudwatch_metric_alarm" "high_latency" {
alarm_name = "order-service-high-latency"
comparison_operator = "GreaterThanThreshold"
evaluation_periods = 3
metric_name= "Duration"
namespace = "AWS/Lambda"
period = 60
statistic = "p99"
threshold = 2000
alarm_description= "P99レイテンシが2秒を超過"
alarm_actions = [aws_sns_topic.alerts.arn]
dimensions = {
FunctionName = "order-processor"
}
}
2-3. コスト設計 × セキュリティ連携
CloudWatch のコスト設計は Observability 導入前に必ず計画します。コストに直結する3要素:
| コスト要因 | 課金モデル | 最適化の方針 |
|---|---|---|
| カスタムメトリクス | $0.30/メトリクス/月 (最初の10,000個) | 不要メトリクスを削除。標準メトリクスを優先活用 |
| CloudWatch Logs 取り込み | $0.76/GB | ログレベルを本番は WARN 以上に設定。DEBUG は開発のみ |
| X-Ray トレース | $5.00/100万トレース | サンプリングレート調整。重要エンドポイントのみ高頻度 |
| Logs 保存 | $0.033/GB/月 | 保持期間を環境ごとに設定 (本番90日 / 開発30日) |
セキュリティ本格運用 Vol1 の CloudTrail × CloudWatch Logs 連携を活用することで、セキュリティイベント (API コール異常・権限エスカレーション) を Observability パイプラインに統合できます。CloudWatch Logs に流れた CloudTrail ログを Logs Insights でクエリし、アプリケーションログと横断分析することが可能です。
コスト最適化 Vol1 の CloudWatch コスト配分タグと組み合わせると、サービス別 SLO 達成率 × コストの相関分析が可能になります。「高コストだが SLO を大幅に達成しているサービス」と「低コストだが SLO 未達のサービス」を定量的に比較し、投資対効果の高いコスト最適化判断ができます。
- メトリクス・トレース・ログを3点セットで設計せよ: 単独では根本原因特定不可 — 3本柱の連携が問題解決を加速する。導入順序はメトリクス → ログ → トレースが現実的
- SLI → SLO → エラーバジェット の順で設計せよ: 計測対象 (SLI) を決めずに目標 (SLO) を設定しても意味がない。Application Signals で自動 SLI 計測から始めよ
- CloudWatch コストを設計段階で見積もれ: カスタムメトリクス・ログ保存期間・X-Ray サンプリング率がコストに直結する。本番投入前に AWS Pricing Calculator で試算せよ
3. Application Signals実践 (山場1) — SLI / SLO / エラーバジェット / Service map / Burn rate alarm

3-1. Application Signals の役割 — SLI/SLO 自動計測の全体像
AWS Application Signals は、AWS マネージドの SLI/SLO 自動計測サービスだ。従来の観測では「エラーが起きたら通知する」レベルにとどまっていたが、Application Signals はサービスレベル目標 (SLO) を定義し、エラーバジェットの残量を継続的に計測することで、「いつリリースを止めるべきか」「どの段階でアラームを上げるべきか」を定量的に判断できる基盤を提供する。
Application Signals が自動計測できる4サービス
| サービス | 計測方法 | 取得できるメトリクス |
|---|---|---|
| API Gateway | マネージド統合 (追加設定不要) | レイテンシ / エラー率 / スループット |
| Lambda | Lambda Insights 拡張 | 実行時間 / エラー率 / スロットリング |
| ECS | CloudWatch Container Insights + ADOT | コンテナ別レイテンシ / エラー率 |
| EKS | ADOT Collector + Operator | Pod別 / Namespace別 SLI |
手動での計装コードが不要な点が最大の特徴だ。CloudWatch エージェントまたは ADOT Collector を導入するだけで、SLI 計測がすぐに開始できる。
SLI / SLO / エラーバジェット の3層構造
【SRE 3層構造】
SLI (Service Level Indicator) → 計測指標
例: 成功リクエスト率 / p99レイテンシ / エラー率
↓ 目標値を設定する
SLO (Service Level Objective) → 達成目標
例: 可用性 SLO = 99.9% (月間)
レイテンシ SLO = p99 < 1秒 を 99% 保証
エラー率 SLO = 5xx < 0.1%
↓ 余裕を定量化する
エラーバジェット (Error Budget) → 許容できる失敗量
例: 99.9% SLO → 月間 0.1% = 約43分の障害を許容
バジェット残量 = 新機能リリースの可否判断に使う
IAM Permission棚卸自動化Vol3で学んだCloudWatch Logsの権限管理を、Application Signals のIAMロール設計に応用せよ。cloudwatch:GetMetricData / application-signals:GetService / application-signals:ListServiceLevelObjectives の3アクションを最小権限で付与することで、SLO閲覧専用ロールとSLO管理ロールを分離できる。
3-2. SLI/SLO 設計実践 — 可用性・レイテンシ・エラー率
SLO 設計の3パターン
| SLO種別 | SLI | 目標値例 | ウィンドウ |
|---|---|---|---|
| 可用性 SLO | 成功レスポンス数 / 全リクエスト数 | 99.9% | 28日ローリング |
| レイテンシ SLO | p99レイテンシ < 閾値 のリクエスト率 | 99% | 28日ローリング |
| エラー率 SLO | 5xx以外のレスポンス数 / 全リクエスト数 | 99.9% | 28日ローリング |
エラーバジェット計算
【可用性 SLO 99.9% のエラーバジェット】
28日ローリングウィンドウ:
28日 × 24時間 × 60分 = 40,320分
許容ダウンタイム = 40,320 × 0.001 = 40.32分
1時間あたりの許容エラー率 = 0.001 (= 0.1%)
Fast Burn で1時間に2%消費 → 残り約2時間でバジェット枯渇
Terraform による Application Signals SLO 設定
resource "aws_applicationsignals_service_level_objective" "api_availability" {
name = "api-availability-slo"
description = "API Gateway availability SLO — 99.9% 28-day rolling"
sli {
sli_metric {
key_attributes = {
"Environment" = "production"
"Name" = "api-gateway"
"Type" = "Service"
}
metric_type = "AVAILABILITY"
operation_name = "GET /api/users"
}
comparison_operator = "GreaterThanOrEqualTo"
metric_threshold = 0.999
}
goal {
attainment_goal= 99.9
warning_threshold = 99.5
interval {
rolling_interval {
duration= 28
duration_unit = "DAY"
}
}
}
}
resource "aws_applicationsignals_service_level_objective" "api_latency" {
name = "api-latency-slo"
description = "API Gateway p99 latency SLO — p99 < 1s を 99% 保証"
sli {
sli_metric {
key_attributes = {
"Environment" = "production"
"Name" = "api-gateway"
"Type" = "Service"
}
metric_type = "LATENCY"
operation_name = "GET /api/users"
}
comparison_operator = "LessThan"
metric_threshold = 1000
}
goal {
attainment_goal= 99.0
warning_threshold = 98.5
interval {
rolling_interval {
duration= 28
duration_unit = "DAY"
}
}
}
}
attainment_goal はSLO目標値 (例: 99.9) で、warning_threshold はアラームを上げる手前の警告ラインだ。warning_threshold を設定することで、SLO違反前の段階でチームに注意を促せる。
3-3. Burn Rate アラーム設計 — Fast Burn / Slow Burn
エラーバジェットの消費速度を示す Burn Rate を監視することで、SLO違反を早期に検知できる。単純な閾値アラームでは「SLO違反直前」まで気づけないが、Burn Rate アラームは「このペースで消費が続くとN時間後に違反する」を予測的に検知する。
Fast Burn / Slow Burn の2段階設計
| アラーム種別 | 判定基準 | 検知感度 | 対応優先度 |
|---|---|---|---|
| Fast Burn (Critical) | 1時間でエラーバジェットの2%消費 → バジェット枯渇まで約2時間 | 高 (誤検知リスクあり) | 即時対応 |
| Slow Burn (Warning) | 6時間でエラーバジェットの10%消費 → バジェット枯渇まで約60時間 | 低 (じわじわ悪化を検知) | 計画的対応 |
Fast Burn のみでは「ゆっくり悪化するケース」を見逃す。Slow Burn と組み合わせることで、急激な障害とじわじわ積み上がる問題の両方を捕捉できる。
Terraform による Burn Rate アラーム設定
resource "aws_cloudwatch_metric_alarm" "fast_burn" {
alarm_name = "api-availability-slo-fast-burn"
alarm_description= "Fast Burn: エラーバジェット消費が危機的速度"
comparison_operator = "GreaterThanThreshold"
evaluation_periods = 1
threshold = 14.4
metric_query {
id = "burn_rate"
expression = "errors/requests * (1/(1-0.999))"
label = "Burn Rate"
return_data = true
}
metric_query {
id = "errors"
metric {
metric_name = "5xxError"
namespace= "AWS/ApiGateway"
period= 3600
stat = "Sum"
dimensions = { ApiName = "production-api" }
}
}
metric_query {
id = "requests"
metric {
metric_name = "Count"
namespace= "AWS/ApiGateway"
period= 3600
stat = "Sum"
dimensions = { ApiName = "production-api" }
}
}
alarm_actions = [aws_sns_topic.critical.arn]
}
resource "aws_cloudwatch_metric_alarm" "slow_burn" {
alarm_name = "api-availability-slo-slow-burn"
alarm_description= "Slow Burn: エラーバジェット消費が警戒速度"
comparison_operator = "GreaterThanThreshold"
evaluation_periods = 6
threshold = 6.0
metric_query {
id = "burn_rate"
expression = "errors/requests * (1/(1-0.999))"
label = "Burn Rate"
return_data = true
}
metric_query {
id = "errors"
metric {
metric_name = "5xxError"
namespace= "AWS/ApiGateway"
period= 3600
stat = "Sum"
dimensions = { ApiName = "production-api" }
}
}
metric_query {
id = "requests"
metric {
metric_name = "Count"
namespace= "AWS/ApiGateway"
period= 3600
stat = "Sum"
dimensions = { ApiName = "production-api" }
}
}
alarm_actions = [aws_sns_topic.warning.arn]
}
マルチアカウント運用Vol1のCross-Account CloudWatch Metricsと組み合わせることで、複数アカウントにデプロイされたサービスのSLOを管理アカウントで一元監視できる。Monitoring AccountにCloudWatchクロスアカウントオブザーバビリティを有効化し、全本番アカウントのBurn Rateアラームを集約すれば、SLO管理の視点が組織全体に広がる。
3-4. Burn Rate 自動対応フローと DR 連携

復旧・運用編Vol1: Multi-Region Backup/DRのRPO/RTOとSLOを連動させよ。DR発動時はフェイルオーバー期間中もリクエストが失敗するため、エラーバジェットが急激に消費される。DR発動の判断基準を「RTOを超えた場合」ではなく「SLOのFast BurnがCriticalになった場合」に設定することで、ビジネスへの影響を定量的に評価した上でフェイルオーバーを実行できる。
エラーバジェットとリリース判断の連動
【デプロイ判断フレームワーク】
エラーバジェット残量 > 50% → 通常リリース OK
エラーバジェット残量 20〜50% → リリースはリスク評価後
エラーバジェット残量 < 20% → 新機能リリース凍結
エラーバジェット残量 0% (枯渇) → 全デプロイ停止 / 復旧最優先
エラーバジェットをリリースの「通貨」として使うことで、開発速度とサービス品質のトレードオフを定量的に管理できる。Terraform の aws_applicationsignals_service_level_objective リソースで定義したSLOは、CloudWatch ダッシュボードと連携してバジェット残量をリアルタイムで可視化できる。
- SLI → SLO → エラーバジェット の順で設計せよ: 計測できないSLIに基づくSLOは意味を持たない — Application Signals の自動計測可能な指標から始めよ
- Fast Burn / Slow Burn の2段階アラームを必ず設定せよ: Fast Burn のみでは重大な消費を見逃す — Slow Burn で「じわじわ悪化」を早期検知せよ
- エラーバジェットをリリース判断に組み込め: バジェット残量が少ない時は新機能リリースを延期 — SLO とデプロイ戦略を連動させよ
4. X-Ray分散トレーシング実践 (山場2) — Service map / Sampling Rules / Trace analytics / Trace ID伝搬

4-1. X-Ray の役割 — Service Map で分散システムの依存関係を可視化
AWS X-Ray は、マイクロサービスアーキテクチャにおけるリクエストの流れをエンドツーエンドでトレーシングするサービスである。単一のリクエストが複数のサービスをまたいで処理される際、各サービスのレイテンシ・エラー率・スループットをService Mapとして視覚化することで、ボトルネックと障害の波及経路を即座に特定できる。
Service Map の主要メトリクス
| 指標 | 内容 | 活用場面 |
|---|---|---|
| レイテンシ (p50/p90/p99) | 各サービスの応答時間分布 | SLO違反の根本原因特定 |
| エラー率 (4xx/5xx) | クライアント/サーバーエラーの割合 | 異常サービスの即時発見 |
| スロットリング率 | ThrottledException の割合 | リソース容量計画 |
| フォルト率 | 5xx + 例外の合計割合 | サービス品質の継続監視 |
セグメントとサブセグメントの構造
トレース
└── セグメント: API Gateway (トレースID生成・合計レイテンシ記録)
├── サブセグメント: Lambda実行 (コールドスタート検知)
│├── サブセグメント: DynamoDB GetItem (テーブル名・キー記録)
│└── サブセグメント: S3 PutObject (バケット名・レイテンシ)
└── サブセグメント: SQS SendMessage (キューURL・メッセージID)
セグメントはサービス単位の処理を表し、サブセグメントはAWS SDK呼び出し・SQLクエリ・HTTPリクエスト等の詳細操作を記録する。Lambda関数は自動でサブセグメントを生成するが、カスタムビジネスロジック内の処理は手動でサブセグメントを定義することで、より詳細なパフォーマンス分析が可能となる。
Python SDK でのカスタムサブセグメント定義:
from aws_xray_sdk.core import xray_recorder
@xray_recorder.capture('process_order')
def process_order(order_id: str) -> dict:
# アノテーション: 検索可能なキーバリュー
xray_recorder.current_subsegment().put_annotation('order_id', order_id)
xray_recorder.current_subsegment().put_annotation('request_type', 'order_processing')
# メタデータ: 詳細情報 (検索不可・大容量データ向け)
xray_recorder.current_subsegment().put_metadata('order_details', {
'items': ['item-001', 'item-002'],
'total_amount': 15800
})
with xray_recorder.in_subsegment('dynamodb_write') as subsegment:
subsegment.put_annotation('table', 'orders')
# DynamoDB 書き込み処理
return write_to_dynamodb(order_id)
AIシリーズVol1: Bedrock AgentsのAPI呼び出しをX-Rayでトレーシングすることで、BedrockのInvokeModel呼び出しがどのサービスから発生しているかを追跡可能になる。マルチエージェント構成では、各エージェントのツール呼び出しレイテンシとエラー率をService Mapで一元確認でき、ボトルネックとなるAWS APIを即座に特定できる。
4-2. サンプリング戦略 — コストとカバレッジのバランス最適化
X-Ray のサンプリングはコスト管理の核心である。全リクエストをトレースすると高トラフィック環境ではデータ量が爆発するため、サービス重要度に応じたサンプリングレートの差別化が必須となる。
サンプリングタイプの比較
| タイプ | 動作 | 適用場面 |
|---|---|---|
| 固定レート | 1req/s + 5% (デフォルト) | 低〜中トラフィック汎用 |
| リザーバ方式 | 高トラフィック時も最低1req/sを保証 | SLA重要APIの確実なサンプリング |
| カスタムルール | URL/サービス/メソッドごとに設定 | 細粒度のコスト最適化 |
Terraform によるカスタムサンプリングルール実装:
resource "aws_xray_sampling_rule" "api_high_priority" {
rule_name= "api-high-priority"
priority = 1000
reservoir_size = 5
fixed_rate = 0.1
url_path = "/api/critical/*"
host = "*"
http_method = "*"
service_type= "*"
service_name= "production-api"
resource_arn= "*"
version = 1
}
resource "aws_xray_sampling_rule" "health_check_low" {
rule_name= "health-check-low"
priority = 2000
reservoir_size = 0
fixed_rate = 0.01
url_path = "/health"
host = "*"
http_method = "GET"
service_type= "*"
service_name= "*"
resource_arn= "*"
version = 1
}
resource "aws_xray_sampling_rule" "default_rule" {
rule_name= "default-balanced"
priority = 9000
reservoir_size = 1
fixed_rate = 0.05
url_path = "*"
host = "*"
http_method = "*"
service_type= "*"
service_name= "*"
resource_arn= "*"
version = 1
}
priority の数値が小さいほど優先度が高い。クリティカルAPIを priority=1000・高レートで保護し、ヘルスチェックを priority=2000・1% に抑えることで、意味のあるトレースのみを取得しつつコストを最小化できる。
4-3. X-Ray Insights — 異常トレースパターンの自動検知
X-Ray Insights は、通常状態からの統計的偏差を検知し、異常なトレースパターンを自動でアラートする機能である。手動でダッシュボードを確認しなくても、エラー率・レイテンシ・スロットリングのスパイクを自動検知して通知できる。
Insights で検知できる異常パターン
| 異常タイプ | 検知トリガー | 対応アクション |
|---|---|---|
| エラー率スパイク | 通常比 2σ 以上の増加 | 影響サービスの即時確認 |
| レイテンシ増加 | p99 が閾値を超過 | Service Map でボトルネック特定 |
| スロットリング増加 | ThrottledException 急増 | リソース上限の引き上げ検討 |
| フォルト連鎖 | 複数サービスの同時障害 | 依存関係グラフで波及経路確認 |
アノテーションとメタデータの使い分け
| 属性 | 検索可能 | データ量 | 用途例 |
|---|---|---|---|
| アノテーション | ✅ はい | 小 (文字列) | user_id, request_type, environment |
| メタデータ | ❌ いいえ | 大 (JSON) | SQLクエリ全文, リクエストボディ, デバッグ情報 |
アノテーションはフィルタ式で検索可能なため、障害発生時に特定ユーザーや特定リクエストタイプのトレースを即座に絞り込める。メタデータは検索対象外だが容量制限が緩く、詳細なデバッグ情報の保存に適している。
復旧・運用編Vol2: Chaos Engineering × FISの障害注入実験をX-Ray Service Mapで可視化することで、障害伝播経路をトレースで確認でき実験精度が向上する。FISで意図的にレイテンシを注入した際、どのサービスに波及したかをService Mapのエラー率・レイテンシヒートマップで追跡し、Chaos実験の影響範囲を定量的に評価できる。
X-Ray Analytics によるトレース分析
X-Ray Analytics コンソールでは、フィルタ式を使用してトレースを絞り込み、応答時間の分布・エラー率の時系列変化・リクエスト属性との相関を対話的に分析できる。代表的なフィルタ式:
# エラーが発生した特定ユーザーのトレースを絞り込む
annotation.user_id = "usr-12345" AND fault = true
# p99 レイテンシが 3 秒を超えるトレースの特定
responsetime > 3 AND service("production-api")
# DynamoDB 呼び出しが含まれるトレースのみ表示
service("DynamoDB")
CloudWatch との連携により、X-Ray の ThrottleCount・FaultRate・ErrorRate メトリクスをCloudWatch Dashboardに集約し、Application Signals の SLO ウィジェットと並列表示することで、SLO違反とトレースの相関を一画面で把握できる。
4-4. Terraform 実装 + X-Ray Groups によるトレースフィルタリング
X-Ray Groups は、フィルタ式でトレースをグループ化し、グループ単位でInsightsを有効化できる機能である。本番APIグループと開発環境グループを分離することで、アラートのノイズを削減できる。
resource "aws_xray_group" "production_errors" {
group_name = "production-errors"
filter_expression = "service(\"production-api\") AND fault = true"
insights_configuration {
insights_enabled= true
notifications_enabled = true
}
}
resource "aws_xray_group" "high_latency" {
group_name = "high-latency-detection"
filter_expression = "responsetime > 2 AND service(\"production-api\")"
insights_configuration {
insights_enabled= true
notifications_enabled = false
}
}
X-Ray トレースシーケンス (mermaid02)

Trace ID の伝搬パターン
分散システムでX-Rayを有効活用するには、サービス間でTrace IDを正しく伝搬させることが不可欠である。HTTP通信では X-Amzn-Trace-Id ヘッダーにTraceIDを付与し、SQS/SNSではメッセージ属性として伝搬する。
import boto3
from aws_xray_sdk.core import xray_recorder, patch_all
# AWS SDK全体をX-Rayでパッチ (自動的にサブセグメント生成)
patch_all()
def invoke_downstream_service(payload: dict) -> dict:
# X-Amzn-Trace-Id ヘッダーは patch_all() により自動付与
# SQS経由の場合もメッセージ属性に自動埋め込み
sqs = boto3.client('sqs')
response = sqs.send_message(
QueueUrl=os.environ['QUEUE_URL'],
MessageBody=json.dumps(payload),
# X-Rayトレースヘッダーは patch_all() が自動設定
)
return response
X-Ray コスト見積もりの目安
| トラフィック規模 | サンプリング設定 | 月間トレース数 | 概算コスト |
|---|---|---|---|
| 小規模 (100 req/s) | デフォルト (5%) | ~130万 | ~$1.7 |
| 中規模 (1,000 req/s) | カスタム (1%) | ~260万 | ~$3.3 |
| 大規模 (10,000 req/s) | 重要API 0.5% + HC 0.01% | ~1,300万 | ~$16.9 |
最初の100万トレース/月は無料枠。コスト最適化の観点では、ヘルスチェックやメトリクス収集用のバックグラウンドリクエストを最低レートに抑えることが最も効果的である。
X-Ray Insights の自動検知と組み合わせることで、コストを抑えながらも重要な異常を見逃さない運用体制を実現できる。本番環境ではまずデフォルト設定で運用を開始し、CloudWatchのコストダッシュボードでX-Rayのトレース量を週次確認しながらサンプリングレートを段階的に最適化することを推奨する。
- サンプリングレートはサービス重要度で差別化せよ: 全リクエストをトレースするとコストが爆発する — クリティカルAPIは高レート・ヘルスチェックは最低レートに設定せよ
- アノテーションで検索性を確保せよ: ユーザーID・リクエストタイプ等をアノテーションに設定 — 障害発生時に特定ユーザーのトレースを即座に絞り込める
- Service Map を定期的に確認せよ: 依存関係の変化・新たなボトルネックを早期発見 — 手動ドキュメントより Service Map の方が常に最新状態
5. CloudWatch + ADOT + OpenTelemetry 統合 — EKS Vol2発展

5-1. ADOT の役割 — OpenTelemetry の AWS 最適化ディストリビューション
EKS 本番運用 Vol2: FluentBit / Container Insights / ADOT で学んだ EKS 特化の ADOT 設定を、EC2 / Lambda / ECS を含む全サービス横断の統合観測基盤に拡張する。
ADOT (AWS Distro for OpenTelemetry) は、CNCF の OpenTelemetry プロジェクトの AWS 最適化ディストリビューションだ。OTel 標準に準拠しながら、X-Ray / CloudWatch / Amazon Managed Service for Prometheus (AMP) へのエクスポートを公式サポートする。
ADOT と従来型エージェントの比較
| 観点 | CloudWatch Agent | X-Ray Agent | ADOT Collector |
|---|---|---|---|
| トレース | 非対応 | X-Ray のみ | X-Ray + OTLP 両対応 |
| メトリクス | CloudWatch のみ | 非対応 | CloudWatch EMF + AMP |
| ログ | CloudWatch Logs | 非対応 | CloudWatch Logs + OTLP |
| 標準規格 | 独自形式 | 独自形式 | OpenTelemetry 標準 |
| マルチバックエンド | 非対応 | 非対応 | 同時複数送信可能 |
ADOT の最大のメリットは ベンダー中立性 だ。同じ計装コードで X-Ray / Jaeger / Zipkin / Prometheus など複数のバックエンドに切り替えできる。アプリケーションへの SDK 埋め込みも不要で、Collector 側の設定だけでデータ変換・フィルタリング・ルーティングを制御できる。
OpenTelemetry SDK 対応言語と計装方式
| 言語 | 自動計装 (Auto Instrumentation) | 手動計装 | AWS Exporter |
|---|---|---|---|
| Java | Java Agent (-javaagent) | OTel SDK | ✅ |
| Python | opentelemetry-instrumentation-auto | OTel SDK | ✅ |
| Node.js | @opentelemetry/auto-instrumentations-node | OTel SDK | ✅ |
| Go | 手動のみ (自動計装未対応) | OTel SDK | ✅ |
| .NET | OpenTelemetry.AutoInstrumentation | OTel SDK | ✅ |
自動計装では HTTP / gRPC / DB クライアントのスパンを自動生成するため、アプリコードの変更ゼロで分散トレースを開始できる。Lambda では ADOT Lambda Layer を追加するだけで自動計装が有効になる。
5-2. OpenTelemetry Collector 設計実践
OTel Collector は Receiver → Processor → Exporter のパイプラインで動作する。各コンポーネントを組み合わせてトレース・メトリクス・ログのフローを定義する。
パイプラインコンポーネント一覧
| 種別 | 代表コンポーネント | 用途 |
|---|---|---|
| Receiver | otlp / prometheus / zipkin | データ受信プロトコル |
| Processor | batch / memory_limiter / resource | バッファリング / メモリ制御 / タグ付与 |
| Exporter | awsxray / awsemf / prometheusremotewrite | 送信先指定 |
以下は EKS 上での ADOT Collector を Kubernetes ConfigMap で定義する実践例だ:
apiVersion: v1
kind: ConfigMap
metadata:
name: adot-collector-config
namespace: monitoring
data:
config.yaml: |
receivers:
otlp:
protocols:
grpc:
endpoint: 0.0.0.0:4317
http:
endpoint: 0.0.0.0:4318
prometheus:
config:
scrape_configs:
- job_name: 'kubernetes-pods'
kubernetes_sd_configs:
- role: pod
relabel_configs:
- source_labels: [__meta_kubernetes_pod_annotation_prometheus_io_scrape]
action: keep
regex: "true"
processors:
batch:
timeout: 1s
send_batch_size: 1000
memory_limiter:
check_interval: 1s
limit_mib: 400
spike_limit_mib: 100
resource:
attributes:
- key: cloud.region
value: ap-northeast-1
action: insert
exporters:
awsxray:
region: ap-northeast-1
awsemf:
region: ap-northeast-1
namespace: ObservabilityMetrics
log_group_name: /aws/observability/metrics
prometheusremotewrite:
endpoint: https://aps-workspaces.ap-northeast-1.amazonaws.com/workspaces/{workspace-id}/api/v1/remote_write
auth:
authenticator: sigv4auth
extensions:
sigv4auth:
region: ap-northeast-1
service: aps
service:
extensions: [sigv4auth]
pipelines:
traces:
receivers: [otlp]
processors: [batch, memory_limiter]
exporters: [awsxray]
metrics:
receivers: [otlp, prometheus]
processors: [batch, resource]
exporters: [awsemf, prometheusremotewrite]
5-3. EKS + ADOT 統合パターン
DaemonSet vs Deployment — デプロイ方式の選択
| デプロイ方式 | 適合ケース | メリット | デメリット |
|---|---|---|---|
| DaemonSet | ノード全体のメトリクス収集 | ノード単位で確実に稼働 | ノード数分のリソース消費 |
| Deployment | 集中型トレース集約 | スケーリング自由 | 特定ノードに偏る可能性 |
| Sidecar | Pod 単位の独立性が必要なケース | 疎結合 | リソース効率が最も悪い |
EKS では通常 DaemonSet + Deployment の組み合わせ を推奨する。DaemonSet でノードレベルのメトリクスを収集し、Deployment でアプリケーショントレースを集約する。
IRSA 権限設定 (Terraform)
module "adot_irsa" {
source = "terraform-aws-modules/iam/aws//modules/iam-role-for-service-accounts-eks"
version = "~> 5.0"
role_name = "adot-collector"
oidc_providers = {
main = {
provider_arn= module.eks.oidc_provider_arn
namespace_service_accounts = ["monitoring:adot-collector"]
}
}
role_policy_arns = {
xray = "arn:aws:iam::aws:policy/AWSXrayWriteOnlyAccess"
cw = "arn:aws:iam::aws:policy/CloudWatchAgentServerPolicy"
amp= aws_iam_policy.amp_write.arn
}
}
Container Insights との相違点: Container Insights は EKS ノードレベルの基本メトリクス (CPU / メモリ / ネットワーク) を自動収集するのに対し、ADOT はアプリケーション層の カスタムメトリクス と 分散トレース まで対応する。両者を併用することで観測カバレッジを最大化できる。
ADOT Collector DaemonSet マニフェスト
apiVersion: apps/v1
kind: DaemonSet
metadata:
name: adot-collector
namespace: monitoring
spec:
selector:
matchLabels:
app: adot-collector
template:
metadata:
labels:
app: adot-collector
spec:
serviceAccountName: adot-collector
containers:
- name: adot-collector
image: public.ecr.aws/aws-observability/aws-otel-collector:latest
args: ["--config=/conf/config.yaml"]
resources:
requests:
cpu: 200m
memory: 400Mi
limits:
cpu: 500m
memory: 800Mi
volumeMounts:
- name: config
mountPath: /conf
volumes:
- name: config
configMap:
name: adot-collector-config
5-4. Amazon Managed Service for Prometheus + Managed Grafana
Prometheus はクラウドネイティブの標準的なメトリクス収集ツールだが、自前でクラスタを運用するのはコストがかかる。AWS では Amazon Managed Service for Prometheus (AMP) と Amazon Managed Grafana (AMG) によりフルマネージドで提供される。
AMP + AMG + ADOT の連携フロー
ADOT Collector が prometheusremotewrite エクスポーターで AMP にメトリクスを送信し、Grafana が AMP をデータソースとして可視化する。Grafana 側の認証は IAM / SAML / AWS SSO から選択できる。
AMP ワークスペース作成 (Terraform)
resource "aws_prometheus_workspace" "main" {
alias = "observability-workspace"
tags = { ManagedBy = "terraform" }
}
output "amp_workspace_endpoint" {
value = aws_prometheus_workspace.main.prometheus_endpoint
}
AMP への書き込みには SigV4 署名が必要なため、ADOT Collector の sigv4auth エクステンションを利用する (上記 ConfigMap を参照)。AMG からは AMP ワークスペースをデータソースとして追加するだけで、既存の Grafana ダッシュボードをそのまま活用できる。
- Collector を DaemonSet で展開してサイドカーを排除せよ: Pod 単位のサイドカーはリソース効率が悪い — Node 単位の DaemonSet で集約するのが標準パターン
- memory_limiter Processor を必ず設定せよ: メモリ上限なしでは Collector が OOM で落ちる — 400 MiB 上限を基準に調整せよ
- X-Ray と CloudWatch EMF の両方に同時出力せよ: トレースは X-Ray / メトリクスは CloudWatch EMF — 用途に最適な宛先に分岐することで分析効率を最大化できる
- IRSA で最小権限を付与せよ: Collector に AdministratorAccess を与えず、X-Ray / CloudWatch / AMP への書き込み権限のみに絞る
6. 詰まりポイント7選 図解
詰まりポイント 1: Application Signals 未有効化 — サービスマップに表示されない
Application Signals を有効化しても CloudWatch コンソールのサービスマップに何も表示されない — このトラブルの大半は有効化コマンドの実行漏れとIRSA 権限不足が原因です。aws application-signals start-discovery を実行していないと、SDK がメトリクスを送出していてもサービスマップが構築されません。
# 有効化コマンド (リージョンごとに実行が必要)
aws application-signals start-discovery --region ap-northeast-1
# 有効化状態の確認
aws application-signals get-service-level-objective \
--id dummy 2>&1 | grep -v "ResourceNotFoundException" \
|| echo "Application Signals 有効化済み"
IRSA に付与する IAM ポリシーには application-signals:PutServiceLevelObjectiveDefinition だけでなく、application-signals:BatchGetServiceLevelObjective や cloudwatch:GetMetricData も含める必要があります。
# Terraform: Application Signals IRSA ポリシー
resource "aws_iam_role_policy" "app_signals" {
name = "app-signals-policy"
role = aws_iam_role.app_pod.id
policy = jsonencode({
Version = "2012-10-17"
Statement = [
{
Effect = "Allow"
Action = [
"application-signals:PutServiceLevelObjectiveDefinition",
"application-signals:BatchGetServiceLevelObjective",
"application-signals:ListServiceLevelObjectives",
"cloudwatch:GetMetricData",
"cloudwatch:PutMetricData",
"xray:PutTraceSegments",
"xray:PutTelemetryRecords",
"xray:GetSamplingRules",
"xray:GetSamplingTargets"
]
Resource = "*"
}
]
})
}
- リージョンごとに start-discovery を実行せよ: グローバル設定ではない — デプロイ先リージョン全てで個別実行が必要
- IRSA に application-signals:* と xray:GetSamplingRules を含めよ: どちらか一方が欠けてもサービスマップが構築されない
- 有効化後 5〜10 分待機せよ: Application Signals のサービス検出はリアルタイムではなく数分のラグがある
詰まりポイント 2: サンプリングレート設定ミス — X-Ray コスト爆発とデータ欠損
fixed_rate=1.0 (全トレース収集) を本番で設定すると、高トラフィック時に X-Ray のコストが数十倍に膨れ上がります。逆に fixed_rate=0.001 に絞りすぎると希少なエラートレースが欠損し、障害調査で手詰まりになります。
# ❌ 問題: 本番で全トレース収集
{
"version": 2,
"rules": [
{
"description": "全収集ルール",
"host": "*",
"http_method": "*",
"url_path": "*",
"fixed_target": 1,
"rate": 1.0
}
],
"default": {
"fixed_target": 1,
"rate": 1.0
}
}
# ✅ 正解: 用途別サンプリングルール
{
"version": 2,
"rules": [
{
"description": "エラーパスは高サンプリング",
"host": "*",
"http_method": "*",
"url_path": "/api/payment/*",
"fixed_target": 5,
"rate": 0.1
},
{
"description": "ヘルスチェックは除外",
"host": "*",
"http_method": "GET",
"url_path": "/health",
"fixed_target": 0,
"rate": 0.0
}
],
"default": {
"fixed_target": 1,
"rate": 0.05
}
}
- 本番の default rate は 0.05 (5%) を起点に調整せよ: 1.0 を本番で設定すると月額コストが 20 倍になる実績あり
- 決済・認証エンドポイントは 10〜20% に上げよ: 希少エラーを見逃さないよう高負荷パスほど高くする
- ヘルスチェック系は rate=0.0 で除外せよ: /health /ping /metrics は全件収集しても分析価値がない
詰まりポイント 3: SLO Burn Rate アラーム誤設定 — Fast Burn と Slow Burn の混同
Application Signals の Burn Rate アラームは Fast Burn (短期急激消費) と Slow Burn (長期じわじわ消費) の2段階設定が推奨されています。どちらか一方だけを設定すると、片方のシナリオで無警告のまま SLO を割り込みます。
# ✅ 正解: Fast Burn + Slow Burn 二重設定
resource "aws_cloudwatch_metric_alarm" "slo_fast_burn" {
alarm_name = "slo-fast-burn-14x"
comparison_operator = "GreaterThanThreshold"
evaluation_periods = 1
threshold = 14 # 14x burn rate = 1時間でエラーバジェット 5.6% 消費
metric_query {
id = "burn_rate"
expression = "1 - (success_count / total_count)"
label = "Error Rate"
return_data = true
}
alarm_actions = [aws_sns_topic.pagerduty.arn]
}
resource "aws_cloudwatch_metric_alarm" "slo_slow_burn" {
alarm_name = "slo-slow-burn-6h-2x"
comparison_operator = "GreaterThanThreshold"
evaluation_periods = 6 # 6時間ウィンドウ
threshold = 2# 2x burn rate = 6時間でエラーバジェット 10% 消費
alarm_actions = [aws_sns_topic.slack_alert.arn]
}
- Fast Burn は 14x / 1時間ウィンドウ / PagerDuty 直送を基準にせよ: 1時間で月次エラーバジェットの 5.6% が消えるペースは即時対応が必要
- Slow Burn は 2x / 6時間ウィンドウ / Slack 通知を基準にせよ: じわじわ消費は翌日対応で間に合うが見逃しがち
- エラーバジェット残量 10% でも別アラームを設定せよ: Burn Rate だけでは残量ゼロが見えない
詰まりポイント 4: ADOT Collector メモリ不足 — OOM でトレースが欠損
ADOT Collector を DaemonSet で展開する際に memory_limiter Processor を設定しないと、高トラフィック時に Collector が OOM で強制終了し、トレースデータが欠損します。再起動するまでの数十秒間はトレースが全ロストします。
# ❌ 問題: memory_limiter 未設定
processors:
batch:
timeout: 1s
send_batch_size: 1024
# ✅ 正解: memory_limiter を先頭に配置
processors:
memory_limiter:
check_interval: 1s
limit_mib: 400 # Node の要求 MiB の 80% 以下に設定
spike_limit_mib: 100 # 瞬間スパイク許容量
batch:
timeout: 1s
send_batch_size: 1024
service:
pipelines:
traces:
receivers: [otlp]
# memory_limiter は必ず最初に配置
processors: [memory_limiter, batch]
exporters: [awsxray]
# Terraform: DaemonSet リソース制限
resource "kubernetes_daemonset" "adot_collector" {
spec {
template {
spec {
container {
name = "adot-collector"
resources {
limits = {
memory = "500Mi"
cpu = "256m"
}
requests = {
memory = "400Mi"
cpu = "128m"
}
}
}
}
}
}
}
- memory_limiter を pipeline の先頭に必ず配置せよ: 後ろに置いても batch が先にメモリを確保してしまい効果がない
- limit_mib は Pod requests の 80% に設定せよ: requests=500Mi なら limit_mib=400 が安全な基準値
- spike_limit_mib は limit_mib の 25% を上限にせよ: 瞬間スパイクが limit_mib を超えるとデータをドロップする仕様
詰まりポイント 5: OpenTelemetry SDK バージョン不整合 — Collector との互換性問題
アプリケーション側の OpenTelemetry SDK と ADOT Collector のバージョンが合わない場合、トレースデータが Collector に届いてもサイレントドロップされます。エラーログが出ない場合もあり、発見が遅れがちです。
# ❌ 問題: SDK と Collector の OTLP プロトコルバージョンが不整合
# SDK: opentelemetry-sdk==1.20.0 (OTLP/gRPC proto v1)
# Collector: adot-collector:v0.35.0 (OTLP/gRPC proto v0.19 互換)
from opentelemetry.exporter.otlp.proto.grpc.trace_exporter import OTLPSpanExporter
exporter = OTLPSpanExporter(endpoint="http://adot-collector:4317")
# → プロトコル不整合でサイレントドロップ
# ✅ 正解: バージョンを固定して整合を確認
# requirements.txt
# opentelemetry-sdk==1.24.0
# opentelemetry-exporter-otlp==1.24.0
# opentelemetry-instrumentation-flask==0.45b0
# Collector バージョン確認
# adot-collector:v0.40.0 → SDK 1.24.x 対応
# バージョン整合確認スクリプト
kubectl exec -it adot-collector-xxxxx -- \
/otelcol-contrib --version
# Collector の接続ログ確認
kubectl logs adot-collector-xxxxx | grep "OTLP"
# "Everything is ready. Begin running and processing data." が出るか確認
- SDK・Exporter・Instrumentation の3つを同一バージョンに固定せよ: opentelemetry-sdk と opentelemetry-exporter-otlp は必ず同バージョン
- Collector の変更時は SDK との互換マトリクスを確認せよ: ADOT Collector の CHANGELOG に対応 SDK バージョンが記載されている
- Collector ログの “dropped spans” を定常監視せよ: サイレントドロップは CloudWatch Metric でも捕捉できる (otelcol_exporter_send_failed_spans)
詰まりポイント 6: Cross-Account CloudWatch Metrics 権限設定漏れ
マルチアカウント構成で中央監視アカウントから各ワークロードアカウントの CloudWatch メトリクスを参照する場合、Monitoring Account の IAM ロールとSource Account の CloudWatch Observability Access Manager (OAM) 設定の両方が揃わないとメトリクスが表示されません。
# Source Account 側: OAM Link 作成
resource "aws_oam_link" "to_monitoring" {
label_template = "$AccountName"
resource_types = [
"AWS::CloudWatch::Metric",
"AWS::Logs::LogGroup",
"AWS::XRay::Trace"
]
sink_identifier = "arn:aws:oam:ap-northeast-1:MONITORING_ACCOUNT_ID:sink/SINK_ID"
}
# Monitoring Account 側: OAM Sink ポリシー
resource "aws_oam_sink_policy" "allow_sources" {
sink_identifier = aws_oam_sink.central.id
policy = jsonencode({
Version = "2012-10-17"
Statement = [{
Effect = "Allow"
Principal = { AWS = "arn:aws:iam::SOURCE_ACCOUNT_ID:root" }
Action = "oam:CreateLink"
Resource = "*"
Condition = {
StringEquals = {
"oam:ResourceTypes" = [
"AWS::CloudWatch::Metric",
"AWS::Logs::LogGroup",
"AWS::XRay::Trace"
]
}
}
}]
})
}
- OAM Link は Source Account 側で作成し、OAM Sink は Monitoring Account 側で作成せよ: 逆に設定すると権限エラーで接続できない
- ResourceTypes に Metric・LogGroup・Trace の3つを明示せよ: 省略するとデフォルトが適用されず接続が不完全になる
- マルチアカウント運用 Vol1 の Cross-Account 設計と連動して OAM Sink ARN を Parameter Store で共有せよ: ハードコードは設定変更時の更新漏れを招く
詰まりポイント 7: X-Ray Service Map のサービス名重複 — 同一名の複数サービスが混在
複数のマイクロサービスが同じ service.name を OpenTelemetry の Resource Attribute に設定すると、X-Ray Service Map 上で1つのノードに複数サービスが混在し、トレースの追跡が不可能になります。特に EKS 上でテンプレートをコピーして Deployment を作成する際に起きやすい問題です。
# ❌ 問題: service.name が全サービスで同じ
from opentelemetry.sdk.resources import Resource
resource = Resource(attributes={
"service.name": "my-app", # 全サービスで同一名
"service.version": "1.0.0"
})
# ✅ 正解: 環境変数からサービス名を注入
import os
resource = Resource(attributes={
"service.name": os.environ.get("OTEL_SERVICE_NAME", "unknown-service"),
"service.namespace": os.environ.get("OTEL_SERVICE_NAMESPACE", "default"),
"service.version": os.environ.get("APP_VERSION", "0.0.0"),
"deployment.environment": os.environ.get("ENVIRONMENT", "dev")
})
# Kubernetes Deployment: 環境変数で service.name を注入
env:
- name: OTEL_SERVICE_NAME
value: "payment-service" # サービスごとに異なる名前を設定
- name: OTEL_SERVICE_NAMESPACE
value: "ecommerce"
- name: OTEL_EXPORTER_OTLP_ENDPOINT
value: "http://adot-collector.monitoring:4317"
EKS本番運用 Vol1: Cluster設計/IRSA/ALB の IRSA 命名規則と組み合わせて、X-Ray のサービス名も設計段階からユニーク性を確保し、<namespace>/<service-name> 形式で統一することで、マルチテナント環境での混在を防止できます。
- service.name は環境変数 OTEL_SERVICE_NAME から必ず注入せよ: コードにハードコードすると CI/CD テンプレートコピー時に重複が発生する
- service.namespace で論理グループを作れ: チーム名・ドメイン名を namespace に設定すると Service Map のフィルタリングが容易になる
- EKS Vol1 の IRSA 命名規則と揃えて <namespace>/<service-name> 形式で統一せよ: X-Ray と IAM の命名が一致すると権限調査が大幅に効率化される
7. アンチパターン→正解パターン変換演習 (Terraform + ADOT yaml + OpenTelemetry SDK 3形式)
演習1 (Terraform): SLO 設定ミス — attainment_goal と sli_metric の不整合
以下の Terraform コードには SLO 設定に重大なミスが含まれています。どこが問題か特定し、修正してください。
# ❌ 問題のコード (どこが問題か?)
resource "aws_cloudwatch_metric_alarm" "slo_breach" {
alarm_name = "payment-api-slo-breach"
comparison_operator = "LessThanThreshold"
evaluation_periods = 5
datapoints_to_alarm = 5
threshold = 99.9 # SLO: 99.9% 可用性
metric_query {
id = "availability"
# 問題: エラーレートを計算しているが SLO は可用性で設定している
expression = "errors / total * 100"
label = "Error Rate (%)"
return_data = true
}
metric_query {
id = "errors"
metric {
namespace= "AWS/ApplicationSignals"
metric_name = "Fault"
period= 60
stat = "Sum"
}
}
metric_query {
id = "total"
metric {
namespace= "AWS/ApplicationSignals"
metric_name = "Error" # 問題: Fault と Error を混在
period= 60
stat = "Sum"
}
}
}
# ✅ 正解コード
resource "aws_cloudwatch_metric_alarm" "slo_breach" {
alarm_name = "payment-api-slo-breach"
comparison_operator = "LessThanThreshold"
evaluation_periods = 5
datapoints_to_alarm = 5
threshold = 99.9 # SLO: 99.9% 可用性
metric_query {
id = "availability"
# 修正: 可用性 (成功率) を直接計算
expression = "(total - errors) / total * 100"
label = "Availability (%)"
return_data = true
}
metric_query {
id = "errors"
metric {
namespace= "AWS/ApplicationSignals"
metric_name = "Fault"# 修正: 5xx エラーは Fault を使用
period= 60
stat = "Sum"
}
}
metric_query {
id = "total"
metric {
namespace= "AWS/ApplicationSignals"
metric_name = "Latency" # 修正: 全リクエスト数は Latency の Count を使用
period= 60
stat = "SampleCount"
}
}
}
ポイント解説: Error は 4xx クライアントエラー、Fault は 5xx サーバーエラーです。SLO の可用性計算には Fault のみを使用し、全リクエスト数は Latency の SampleCount から取得するのが Application Signals の正しいパターンです。エラーレート (errors/total) を閾値 99.9 と比較しても論理的に矛盾します。
演習2 (YAML): X-Ray サンプリングルール — 全トレース収集でコスト爆発
# ❌ 問題のコード (どこが問題か?)
# X-Ray Sampling Rules (AWS Console から JSON エクスポート)
{
"version": 2,
"rules": [
{
"description": "全 API トレース",
"host": "*",
"http_method": "*",
"url_path": "/api/*",
"fixed_target": 10,
"rate": 1.0, # 問題: 本番で 100% サンプリング
"priority": 1
},
{
"description": "ヘルスチェック",
"host": "*",
"http_method": "GET",
"url_path": "/health",
"fixed_target": 1,
"rate": 1.0, # 問題: ヘルスチェックも全収集
"priority": 2
}
],
"default": {
"fixed_target": 1,
"rate": 1.0 # 問題: デフォルトも 100%
}
}
# ✅ 正解コード
{
"version": 2,
"rules": [
{
"description": "決済 API: 高サンプリング",
"host": "*",
"http_method": "*",
"url_path": "/api/payment/*",
"fixed_target": 5,
"rate": 0.1, # 修正: 10% サンプリング (高価値エンドポイント)
"priority": 1
},
{
"description": "ヘルスチェック: 除外",
"host": "*",
"http_method": "GET",
"url_path": "/health",
"fixed_target": 0,
"rate": 0.0, # 修正: ヘルスチェックは収集不要
"priority": 2
},
{
"description": "その他 API: 標準",
"host": "*",
"http_method": "*",
"url_path": "/api/*",
"fixed_target": 1,
"rate": 0.05,# 修正: 5% サンプリング
"priority": 10
}
],
"default": {
"fixed_target": 1,
"rate": 0.01# 修正: デフォルトは 1%
}
}
ポイント解説: fixed_target は毎秒必ず収集するトレース数 (最低保証)、rate はその後の割合サンプリングです。本番では rate=1.0 は禁忌 — リクエスト 10,000 件/分の API で全収集すると月額 X-Ray コストが数万円超になります。ヘルスチェックは rate=0.0 で完全除外が最適解です。
演習3 (Terraform): ADOT Collector — memory_limiter 未設定で OOM
# ❌ 問題のコード (どこが問題か?)
resource "kubernetes_config_map" "adot_config" {
metadata {
name= "adot-collector-config"
namespace = "monitoring"
}
data = {
"config.yaml" = <<-EOF
receivers:
otlp:
protocols:
grpc:
endpoint: 0.0.0.0:4317
processors:
batch:# 問題: memory_limiter がない
timeout: 1s
send_batch_size: 1024
exporters:
awsxray:
region: ap-northeast-1
service:
pipelines:
traces:
receivers: [otlp]
processors: [batch]# 問題: memory_limiter なし
exporters: [awsxray]
EOF
}
}
# ✅ 正解コード
resource "kubernetes_config_map" "adot_config" {
metadata {
name= "adot-collector-config"
namespace = "monitoring"
}
data = {
"config.yaml" = <<-EOF
receivers:
otlp:
protocols:
grpc:
endpoint: 0.0.0.0:4317
processors:
memory_limiter: # 修正: 必ず追加
check_interval: 1s
limit_mib: 400
spike_limit_mib: 100
batch:
timeout: 1s
send_batch_size: 1024
exporters:
awsxray:
region: ap-northeast-1
service:
pipelines:
traces:
receivers: [otlp]
processors: [memory_limiter, batch] # 修正: memory_limiter を先頭に
exporters: [awsxray]
EOF
}
}
ポイント解説: memory_limiter は pipeline の最初に配置しないと効果がありません。batch が先に実行されるとメモリ上限前にバッファが膨らみ、OOM で Collector が落ちます。Kubernetes の resources.limits.memory (500Mi) の 80% を limit_mib に設定するのが安全な計算式です。
演習4 (Python SDK): OpenTelemetry Tracer — span を close せず親子関係が壊れる
# ❌ 問題のコード (どこが問題か?)
from opentelemetry import trace
tracer = trace.get_tracer(__name__)
def process_payment(order_id: str):
span = tracer.start_span("process_payment") # 問題: context manager を使っていない
try:
# 処理中に例外が発生したら span が閉じられない
result = charge_credit_card(order_id)
span.set_attribute("order.id", order_id)
return result
except Exception as e:
span.record_exception(e)
raise
# 問題: span.end() が呼ばれないケースがある
def charge_credit_card(order_id: str):
# 問題: 親 span が明示されていないため子 span が孤立する
child_span = tracer.start_span("charge_credit_card")
result = external_payment_api(order_id)
child_span.end()
return result
# ✅ 正解コード
from opentelemetry import trace
from opentelemetry.trace import SpanKind
tracer = trace.get_tracer(__name__)
def process_payment(order_id: str):
# 修正: context manager で必ず span が閉じられる
with tracer.start_as_current_span(
"process_payment",
kind=SpanKind.SERVER
) as span:
span.set_attribute("order.id", order_id)
try:
result = charge_credit_card(order_id)
span.set_attribute("payment.status", "success")
return result
except Exception as e:
span.record_exception(e)
span.set_status(trace.StatusCode.ERROR, str(e))
raise
def charge_credit_card(order_id: str):
# 修正: start_as_current_span が自動的に親子関係を構築
with tracer.start_as_current_span(
"charge_credit_card",
kind=SpanKind.CLIENT
) as span:
span.set_attribute("payment.gateway", "stripe")
result = external_payment_api(order_id)
return result
ポイント解説: start_span() を使うと span.end() を手動で呼ぶ必要があり、例外時に漏れが発生します。start_as_current_span() を context manager として使うと、例外時も含めて span が確実にクローズされ、親子関係 (Context Propagation) も自動で設定されます。X-Ray のサービスマップが途切れる原因の大半がこのパターンです。
演習5 (Terraform): IAM ロール — xray:GetSamplingRules 権限漏れでサンプリングルール取得失敗
# ❌ 問題のコード (どこが問題か?)
data "aws_iam_policy_document" "app_xray" {
statement {
effect = "Allow"
actions = [
"xray:PutTraceSegments",
"xray:PutTelemetryRecords",
# 問題: GetSamplingRules / GetSamplingTargets が欠落
]
resources = ["*"]
}
}
resource "aws_iam_role_policy" "app_xray" {
name= "app-xray-policy"
role= aws_iam_role.app_pod.id
policy = data.aws_iam_policy_document.app_xray.json
}
# ✅ 正解コード
data "aws_iam_policy_document" "app_xray" {
statement {
effect = "Allow"
actions = [
"xray:PutTraceSegments",
"xray:PutTelemetryRecords",
"xray:GetSamplingRules",# 修正: カスタムルール取得に必須
"xray:GetSamplingTargets", # 修正: サンプリングターゲット更新に必須
"xray:GetSamplingStatisticSummaries" # 修正: 統計情報取得 (任意だが推奨)
]
resources = ["*"]
}
}
resource "aws_iam_role_policy" "app_xray" {
name= "app-xray-policy"
role= aws_iam_role.app_pod.id
policy = data.aws_iam_policy_document.app_xray.json
}
ポイント解説: xray:GetSamplingRules が欠けると、アプリケーションは X-Ray コンソールで設定したカスタムサンプリングルールを取得できず、デフォルトの rate=0.05 にフォールバックします。エラーログに AccessDeniedException: GetSamplingRules が出ない場合もあるため、権限不足に気づかないまま意図しないサンプリングが続くことがあります。IRSA への最小権限付与ではこの3権限セットを基準にしてください。
8. まとめ + Vol2予告 + 落とし穴10選 + 全7軸クロスリンク + 第8軸結節点完結宣言
本記事で学んだこと
本記事では AWS Observability の3本柱 (メトリクス / トレース / ログ) を Application Signals・X-Ray・CloudWatch・ADOT の4ツールで統合実装する方法を一気通貫で解説しました。
- Observability 3本柱の統合設計: メトリクス (CloudWatch) / トレース (X-Ray) / ログ (CloudWatch Logs) を分離して考えず、ADOT Collector で一元収集・振り分けするアーキテクチャ
- Application Signals による SLI/SLO 自動化: SLI の手動計算を廃止し、Application Signals が自動計測する Availability / Latency / Error Rate をそのまま SLO に紐づける設計
- エラーバジェット × Burn Rate アラームの実装: Fast Burn (14x/1時間) + Slow Burn (2x/6時間) の二重アラームで「気づくべきときに確実に気づく」監視体制の確立
- X-Ray 分散トレーシングの本番設計: サンプリングルールの用途別設定・Service Map のサービス名ユニーク化・ADOT Collector の OOM 防止設計
- ADOT + OpenTelemetry 統合パイプライン: DaemonSet 展開・memory_limiter 設定・マルチ宛先出力 (X-Ray + CloudWatch EMF + AMP) の設計パターン
- 詰まりポイント7選の完全対策: 有効化漏れ・権限不足・バージョン不整合・OOM・Cross-Account 設定ミスを具体的なコードで解決
本記事は全8軸の第8軸 (Observability実践) として位置づけられています。IAM入門シリーズで確立した最小権限設計、EKS本番運用シリーズで構築したコンテナ基盤、復旧・運用編で整備した障害対応フロー、AIシリーズ・セキュリティ本格運用・コスト最適化・マルチアカウント運用 — これら全7軸の運用状態を Observability がリアルタイムで観測・計測する構造が完成しました。
落とし穴10選
| # | 落とし穴 | 対処法 |
|---|---|---|
| 1 | Application Signals の start-discovery を実行しないままサービスマップを確認 | リージョンごとに aws application-signals start-discovery を実行 |
| 2 | X-Ray で rate=1.0 を本番設定してコスト爆発 | デフォルト rate=0.05・ヘルスチェックは rate=0.0 |
| 3 | Fast Burn のみ設定して Slow Burn を見逃す | 14x/1時間 (Fast) + 2x/6時間 (Slow) の二重アラーム必須 |
| 4 | ADOT Collector に memory_limiter を設定せず OOM | memory_limiter を pipeline 先頭に配置・limit_mib は Pod requests の 80% |
| 5 | SDK と Collector のバージョン不整合でサイレントドロップ | SDK・Exporter・Instrumentation の3つを同一バージョンで固定 |
| 6 | Cross-Account の OAM Link と Sink を逆アカウントで作成 | Link は Source Account・Sink は Monitoring Account で作成 |
| 7 | 複数サービスで同じ service.name を設定して Service Map が混在 | OTEL_SERVICE_NAME 環境変数で各サービス固有名を注入 |
| 8 | SLO の可用性計算で Error と Fault を混在 | 5xx は Fault・4xx は Error・可用性は (total - Fault) / total |
| 9 | start_span() を使って例外時に span が閉じられない | start_as_current_span() を context manager として常に使用 |
| 10 | IRSA に xray:GetSamplingRules を付与せずカスタムルールが無効 | PutTraceSegments + GetSamplingRules + GetSamplingTargets の3点セット必須 |
Vol2 予告: CloudWatch Logs Insights × Metric Streams × Observability Accelerator
Observability実践 Vol2 では、本記事で構築した基盤をさらに発展させます。
- CloudWatch Logs Insights 実践: 複雑な集計クエリ・フィールドのパース・可視化ダッシュボードの自動構築
- CloudWatch Metric Streams: リアルタイムメトリクスを Kinesis Data Firehose 経由で S3・Splunk・Datadog に送出するパイプライン設計
- AWS Observability Accelerator: EKS × Grafana × AMP の「すぐ使える」ダッシュボードセット。Infrastructure / API Server / Java / Python ワークロード別テンプレートの活用
- Cost Intelligence Dashboard との連携: Observability コスト (X-Ray / CloudWatch / ADOT) を可視化してコスト最適化の判断材料を提供
- SLO レポートの自動生成: Lambda × EventBridge による週次 SLO レポート生成と Slack 通知の自動化
- Distributed Tracing のクロスアカウント可視化: マルチアカウント運用 Vol1 と組み合わせて、複数アカウントにまたがるサービスコールを1つのトレースで追跡する構成
Vol2 では本記事で構築した Application Signals × X-Ray の基盤を前提として、より高度な分析・可視化・自動化に踏み込みます。Vol2 は近日公開予定です。
Observability 設計成熟度チェックリスト
本記事の内容を実装後、以下のチェックリストで成熟度を確認してください。全項目クリアできていれば、AWS 本番 Observability として十分な基盤が整っています。
レベル1: 基盤確立 (本記事対象)
- [ ] CloudWatch メトリクス・X-Ray トレース・CloudWatch Logs の3本柱が全サービスで収集されている
- [ ] Application Signals が有効化され、サービスマップにサービスが表示されている
- [ ] SLO が定義され、Fast Burn + Slow Burn の二重アラームが設定されている
- [ ] ADOT Collector が DaemonSet で展開され、memory_limiter が設定されている
- [ ] X-Ray のサンプリングルールが用途別に設定されている (本番 default rate ≤ 0.05)
- [ ] 全サービスで service.name が OTEL_SERVICE_NAME 環境変数から注入されている
- [ ] IRSA に xray:GetSamplingRules が含まれている
レベル2: 高度化 (Vol2 対象)
- [ ] CloudWatch Logs Insights で SLO 違反の根本原因を 5 分以内に特定できる
- [ ] Metric Streams で外部 SIEM / BI ツールにリアルタイムデータが流れている
- [ ] Observability Accelerator のダッシュボードが EKS クラスターに展開されている
- [ ] コスト × SLO の相関ダッシュボードで投資対効果を可視化している
レベル3: 全8軸統合
- [ ] IAM入門で設計した最小権限原則が Observability パイプラインの IRSA にも適用されている
- [ ] EKS本番運用 Vol2 の FluentBit × Container Insights と ADOT が重複収集なく統合されている
- [ ] コスト最適化 Vol1 で設定したコスト配分タグが CloudWatch カスタムメトリクスにも付与されている
- [ ] マルチアカウント運用 Vol1 の中央監視アカウントから全サービスアカウントの Observability データが参照できている
- [ ] セキュリティ本格運用 Vol1 の CloudTrail ログが CloudWatch Logs Insights で Observability パイプラインと横断分析できている
- [ ] AIシリーズ Vol1 の Bedrock API 呼び出しトレースが X-Ray のサービスマップに表示されている
成熟度評価基準: レベル1 = Observability 基盤確立 / レベル2 = データ活用最大化 / レベル3 = 全8軸統合完成。本記事でレベル1 を達成し、Vol2 でレベル2 を目指してください。
チェックリストは定期的に見直し、組織・システムの成長に合わせて達成項目を積み上げていくことが、長期的な Observability 成熟度向上の鍵です。
本記事でAWS本番運用の第8軸 (Observability実践) が確立しました。全8軸 (IAM / EKS / 復旧・運用 / AI / セキュリティ / コスト最適化 / マルチアカウント運用 / Observability) が揃いました。
Observabilityシリーズ: Vol1 (本記事): Application Signals × SLO × X-Ray / Vol2 (近日公開): CloudWatch Logs Insights × Metric Streams × Observability Accelerator
IAM入門4巻: Vol1 / Vol2 / Vol3 / Vol4
復旧・運用編4巻: Vol1 / Vol2 / Vol3 / Vol4
AIシリーズ Vol1: Bedrock Agents 本番運用
セキュリティ本格運用 Vol1: Security Hub × GuardDuty × Audit Manager
コスト最適化 Vol1: Cost Explorer × Budgets × Compute Optimizer
マルチアカウント運用 Vol1: Organizations × Control Tower × Landing Zone
第9軸 Network/VPC設計入門: Network/VPC設計入門 Vol1 — Transit Gateway × VPC Lattice × PrivateLink