ECS Fargate に ADOT サイドカーを設置してメトリクス・トレース・SLO を一元管理する
CloudWatch Application Signals は、アプリケーションのパフォーマンスを SLO(Service Level Objectives)で管理できる APM(Application Performance Monitoring)機能です。AWS Distro for OpenTelemetry(ADOT)サイドカーを ECS Fargate タスクに追加することで、コードを変更せずにメトリクス・ログ・トレースの「オブザーバビリティ三本柱」を実現できます。
このハンズオンでは、既存の ECS Fargate サービスに ADOT コレクターサイドカーを設置し、Application Signals でサービスマップと SLO を確認し、X-Ray でリクエストトレースを可視化します。
| 項目 | 内容 |
|---|---|
| 対象サービス | CloudWatch Application Signals、AWS X-Ray、AWS Distro for OpenTelemetry、ECS Fargate |
| 主な学習内容 | ADOT サイドカー設定・Application Signals 有効化・SLO 作成・X-Ray トレース分析・アラーム設定 |
| 所要時間 | 90〜120 分(待機時間含む) |
| 難易度 | ★★★☆☆(中級者向け) |
| 前提知識 | ECS Fargate の基本操作、コンテナの概念 |
| 費用目安 | 約 1〜3 USD(ECS Fargate 実行時間・X-Ray トレース) |
Application Signals は X-Ray トレースデータをベースに、サービスごとの可用性・レイテンシの SLI(Service Level Indicators)を自動計算します。X-Ray でミクロな障害を、Application Signals でマクロな SLO 遵守状況をそれぞれ確認できます。
| リソース | 詳細 | 備考 |
|---|---|---|
| ECS クラスター | 既存クラスター(Fargate) | 前提として作成済み |
| ECS タスク定義 | アプリ + ADOT サイドカー | このハンズオンで更新 |
| ADOT コレクター | public.ecr.aws/aws-observability/aws-otel-collector:latest | サイドカーとして追加 |
| CloudWatch ロググループ | /ecs/otel-collector | ADOT のログ出力先 |
| SSM パラメーターストア | /otel/config | ADOT 設定ファイル |
| IAM ロール(タスク実行) | 既存ロールに権限追加 | X-Ray / CloudWatch 権限 |
作業リージョンを固定してください。このハンズオンでは ap-northeast-1(東京) を使用します。コンソール右上でリージョンを確認してください。
ECS ハンズオン(ECS Fargate + RDS ハンズオン)または ECS CloudFormation キット(CloudFormation 環境構築キット)を先に完了させてください。このハンズオンでは既存の ECS サービスに対して ADOT サイドカーを追加します。
操作ユーザーに以下の IAM ポリシーが付与されていることを確認します。
AmazonECS_FullAccessCloudWatchFullAccessAWSXRayFullAccessAmazonSSMFullAccessIAMFullAccess(タスク実行ロールへの権限追加用)まず CloudWatch Application Signals を有効化し、ADOT サイドカーが必要とする IAM 権限を ECS ロールに追加します。
AWS マネジメントコンソールで 「CloudWatch」 を検索して開きます。左メニューを下にスクロールし、「Application Signals」 セクションを展開して 「サービス」 をクリックします。
初めて開く場合は「Application Signals を開始する」ボタンが表示されます。「Application Signals を開始する」 をクリックします。
Application Signals の有効化はリージョン単位で行われます。X-Ray トレースや CloudWatch Metrics の使用量に対して課金されます(Application Signals 自体への追加料金はありません)。
AWS マネジメントコンソールで 「IAM」 を検索して開きます。左メニューから 「ロール」 をクリックします。
ECS タスク実行ロール(例: ecsTaskExecutionRole)を検索して選択します。「許可を追加」→「ポリシーをアタッチ」 をクリックし、以下のポリシーを追加します。
| ポリシー名 | 用途 |
|---|---|
| CloudWatchAgentServerPolicy | CloudWatch メトリクス送信 |
| AWSXRayDaemonWriteAccess | X-Ray トレース送信 |
| AmazonSSMReadOnlyAccess | SSM パラメーターストアから設定読み取り |
「許可を追加」 をクリックして保存します。
ECS タスクロール(例: ecsTaskRole)も同様に選択し、以下のポリシーをアタッチします。
| ポリシー名 | 用途 |
|---|---|
| AWSXRayDaemonWriteAccess | X-Ray セグメント送信 |
| CloudWatchAgentServerPolicy | Application Signals メトリクス送信 |
両方の IAM ロールの「許可」タブに上記のポリシーが表示されていれば準備完了です。
ADOT コレクターは YAML 形式の設定ファイルを参照して動作します。SSM パラメーターストアに設定を保存し、ECS タスク定義から参照します。
AWS マネジメントコンソールで 「Systems Manager」 を検索して開きます。左メニューから 「パラメータストア」 をクリックします。
「パラメータを作成」 をクリックし、以下の設定を入力します。
「値」欄に以下の YAML を貼り付けます。
extensions:
health_check:
receivers:
otlp:
protocols:
grpc:
endpoint: 0.0.0.0:4317
http:
endpoint: 0.0.0.0:4318
processors:
batch/traces:
timeout: 1s
send_batch_size: 50
batch/metrics:
timeout: 60s
exporters:
awsxray:
region: ap-northeast-1
awsemf:
region: ap-northeast-1
namespace: ApplicationSignals
log_group_name: /aws/application-signals/data
dimension_rollup_option: NoDimensionRollup
service:
extensions: [health_check]
pipelines:
traces:
receivers: [otlp]
processors: [batch/traces]
exporters: [awsxray]
metrics:
receivers: [otlp]
processors: [batch/metrics]
exporters: [awsemf]
「パラメータを作成」 をクリックします。
パラメーターストアに /otel/config が作成されていれば次のステップに進めます。ARN をメモしておいてください(次のステップで使用します)。
既存の ECS タスク定義に ADOT コレクターコンテナをサイドカーとして追加します。
AWS マネジメントコンソールで 「Elastic Container Service」 を検索して開きます。左メニューから 「タスク定義」 をクリックします。
アプリケーションのタスク定義を選択し、最新のリビジョンをクリックします。「新しいリビジョンを作成」→「新しいリビジョンを作成」 をクリックします。
画面を下にスクロールして 「コンテナを追加」 をクリックし、ADOT コレクターコンテナを設定します。
コンテナ設定の 「ポートマッピング」 で以下を追加します。
| コンテナポート | プロトコル | 用途 |
|---|---|---|
| 4317 | tcp | OpenTelemetry gRPC レシーバー |
| 4318 | tcp | OpenTelemetry HTTP レシーバー |
| 13133 | tcp | Health Check エンドポイント |
「環境変数」 セクションで以下を追加します。
| キー | 値の種類 | 値 |
|---|---|---|
| AOT_CONFIG_CONTENT | ValueFrom | arn:aws:ssm:ap-northeast-1:<アカウントID>:parameter/otel/config |
<アカウントID> は実際の AWS アカウント ID(12 桁)に置き換えてください。アカウント ID はコンソール右上のユーザー名をクリックすると確認できます。または SSM パラメーターストアでパラメーター名をクリックして ARN をコピーしてください。
「ログ設定」 セクションで以下を設定します。
「コンテナを追加」 をクリックしてサイドカーを保存します。
既存のアプリコンテナを選択して編集します。OpenTelemetry SDK にエンドポイントを教えるための環境変数を追加します。
| キー | 値 |
|---|---|
| OTEL_EXPORTER_OTLP_ENDPOINT | http://localhost:4317 |
| OTEL_RESOURCE_ATTRIBUTES | service.name=myapp,service.namespace=production |
| OTEL_METRICS_EXPORTER | otlp |
| OTEL_TRACES_EXPORTER | otlp |
| OTEL_PROPAGATORS | xray,tracecontext,baggage,b3 |
service.name は Application Signals のサービスマップ上でサービスを識別する名前になります。アプリケーションを表す分かりやすい名前を付けてください(例: myapp、api-server)。
画面一番下の 「作成」 をクリックして新しいタスク定義リビジョンを保存します。
タスク定義の最新リビジョンに aws-otel-collector コンテナが追加されていれば成功です。
新しいタスク定義リビジョンを使用するよう ECS サービスを更新します。
ECS コンソール左メニューから 「クラスター」 をクリックし、使用しているクラスターを選択します。
「サービス」 タブでアプリケーションのサービスを選択し、「更新」 をクリックします。
「更新」 をクリックします。デプロイが開始され、ADOT サイドカーを含む新しいタスクが起動します。
サービスの 「デプロイ」 タブでステータスを確認します。「PRIMARY」 ステータスのデプロイが完了するまで待ちます(通常 3〜5 分)。
/ecs/otel-collector ロググループでエラーを確認してくださいデプロイ完了後、ALB の DNS 名にブラウザでアクセスし、アプリケーションが正常に動作することを確認します。数回アクセスしてトレースデータを生成します。
ECS サービスのタスクが「RUNNING」状態になり、ALB 経由でアプリにアクセスできれば次のステップに進めます。
ADOT がデータを収集し始めると、CloudWatch Application Signals にサービスが表示されます。
CloudWatch コンソール左メニューの 「Application Signals」→「サービス」 をクリックします。デプロイから 5〜10 分後に myapp(設定した service.name)が表示されます。
ALB 経由でアプリに数回アクセスした後、1〜2 分待ってからページをリロードしてください。アプリに OpenTelemetry SDK が組み込まれていない場合、ADOT はテレメトリを受信できないためサービスが表示されません。SDK のインストール手順は AWS OTEL ドキュメント を参照してください。
サービス名をクリックして詳細画面を開きます。以下の指標を確認します。
| 指標 | 説明 |
|---|---|
| 可用性 | 成功リクエスト率(エラー率の逆数) |
| レイテンシ (p99) | リクエストの 99% が完了する時間 |
| レイテンシ (p50) | 中央値レイテンシ |
| リクエスト数 | 1 分あたりのリクエスト数 |
| エラー率 | 5xx エラーの割合 |
左メニューから 「Application Signals」→「サービスマップ」 をクリックします。アプリケーションが呼び出すサービス(RDS、S3 など)がグラフで表示されます。各ノードをクリックするとレイテンシやエラー率の詳細が確認できます。
Application Signals にサービスが表示され、可用性・レイテンシのグラフが確認できれば次のステップに進めます。
Application Signals の SLO 機能で、サービスの目標値を設定します。SLO を設定することで、エラーバジェットの消費状況をリアルタイムで監視できます。
CloudWatch コンソール左メニューの 「Application Signals」→「SLO」 をクリックします。「SLO を作成」 をクリックします。
最初に可用性(Availability)の SLO を作成します。
「SLO を作成」 をクリックします。
再度 「SLO を作成」 をクリックして、レイテンシの SLO を作成します。
「SLO を作成」 をクリックします。
SLO 一覧に戻り、作成した 2 つの SLO のステータスを確認します。
| 表示項目 | 説明 |
|---|---|
| ステータス(OK / BREACHING) | 現在 SLO を遵守しているか |
| エラーバジェット残余 | 30 日間の許容違反時間のうち残量 |
| コンプライアンス率 | 実績値(99.9% 等) |
SLO 99.9% の場合、30 日間で許容されるダウンタイムは約 43 分です。これが「エラーバジェット」です。バジェットが残っている間は機能リリースを行い、枯渇したら信頼性改善にリソースを集中させる、という運用指針として活用できます。
SLO 一覧に可用性・レイテンシ SLO が表示されていれば次のステップに進めます。
X-Ray コンソールで個別リクエストのトレースデータを確認します。
AWS マネジメントコンソールで 「X-Ray」 を検索して開きます。または CloudWatch コンソール左メニューの 「X-Ray トレース」→「トレース」 からも開けます。
右上の時間範囲ピッカーで 「直近 30 分」 を選択します。ALB 経由でアプリにアクセスしたリクエストのトレース一覧が表示されます。
ALB 経由でアプリにいくつかリクエストを送信してから再度確認してください。アプリに OpenTelemetry SDK が組み込まれていない場合は X-Ray へのトレース送信が行われません。/ecs/otel-collector のログでエラーがないか確認してください。
トレース ID をクリックしてトレース詳細を開きます。
| 表示項目 | 説明 |
|---|---|
| タイムライン | 各セグメントの開始時刻と所要時間 |
| セグメント | サービス内の処理単位(HTTP ハンドラー、DB クエリ等) |
| サブセグメント | 外部 API 呼び出し・SQL クエリの詳細 |
| アノテーション | カスタム属性(ユーザー ID、オーダー ID 等) |
| メタデータ | 詳細なコンテキスト情報 |
フィルター式フィールドに以下を入力してエラーのあるトレースだけを抽出します。
fault OR error
エラーがある場合はトレース詳細でどのセグメントで失敗したかを確認できます。
X-Ray にトレースが表示され、タイムラインでリクエストの処理時間を確認できれば次のステップに進めます。
サービスマップでサービス間の依存関係とパフォーマンスを視覚的に把握します。
X-Ray コンソール左メニューの 「サービスマップ」 をクリックします。アプリケーション・データベース・外部 API などがノードとして表示され、矢印で依存関係が示されます。
各ノードには以下の情報が色分けで表示されます。
| 表示 | 意味 |
|---|---|
| 緑のリング | 正常なリクエスト(2xx)の割合 |
| 黄のリング | クライアントエラー(4xx)の割合 |
| 赤のリング | サーバーエラー(5xx / fault)の割合 |
| リクエスト数 / 秒 | スループット |
| レイテンシ | 平均応答時間 |
ノードをクリックすると右側のパネルにトレース一覧が表示されます。「トレースを表示」 をクリックすることでそのサービスを経由したトレースに絞り込めます。ボトルネックや高レイテンシの原因を特定するのに活用します。
X-Ray コンソール左メニューの 「分析」→「応答時間の分布」 でレイテンシのヒストグラムを確認します。外れ値(p99 の遅いリクエスト)のトレースを特定できます。
X-Ray サービスマップでアプリとバックエンドサービスの依存関係が可視化されていれば次のステップに進めます。
ADOT が送信した Application Signals メトリクスを CloudWatch ダッシュボードで可視化します。
CloudWatch コンソール左メニューの 「メトリクス」→「すべてのメトリクス」 をクリックします。名前空間一覧に ApplicationSignals が表示されていることを確認します。
ApplicationSignals 名前空間をクリックして、利用可能なメトリクスを確認します。
| メトリクス名 | 説明 |
|---|---|
| Latency | リクエストレイテンシ(p50、p99 等で統計を切り替え可能) |
| Availability | 可用性(成功リクエスト率) |
| Error | クライアントエラー(4xx)リクエスト数 |
| Fault | サーバーエラー(5xx)リクエスト数 |
CloudWatch コンソール左メニューの 「ダッシュボード」→「ダッシュボードの作成」 をクリックします。
「ダッシュボードの作成」 をクリックします。
「ウィジェットの追加」 をクリックして以下のウィジェットを追加します。
ApplicationSignals / Latency(p50、p99 の 2 系列)ApplicationSignals / AvailabilityApplicationSignals / Fault(合計)CPUUtilization と MemoryUtilization各ウィジェットを追加したら 「ダッシュボードを保存」 をクリックします。
ダッシュボード右上の「共有」ボタンから、URL リンクとして共有したり、Slack や PagerDuty と連携するウィジェット画像を取得することができます。
ダッシュボードにメトリクスグラフが表示されれば次のステップに進めます。
エラー率と高レイテンシを検知するアラームを設定し、SLO 違反を早期に検知できるようにします。
CloudWatch コンソール左メニューの 「アラーム」→「すべてのアラーム」→「アラームの作成」 をクリックします。
「メトリクスの選択」 をクリックし、ApplicationSignals → Fault メトリクスを選択して 「メトリクスと条件の指定」 をクリックします。
| 設定項目 | 値 |
|---|---|
| 統計 | 合計 (Sum) |
| 期間 | 5 分 |
| アラーム条件 | 以上 (≥) |
| しきい値 | 5 |
「次へ」 をクリックします。
「ALARM 状態のアクション」で 「通知の追加」 をクリックします。
「トピックの作成」 をクリックします。確認メールが届くので 「Confirm subscription」 リンクをクリックして購読を確認します。
「アラームの作成」 をクリックします。
同様の手順で ApplicationSignals / Latency メトリクスを使用したアラームを作成します。
アラーム一覧に myapp-high-fault-rate が 「データ不十分」 または 「OK」 状態で表示されていれば成功です。
Application Signals の SLO 画面からも直接アラームを作成できます。SLO → 対象 SLO を選択 → 「アラームを作成」ボタンから設定すると、エラーバジェット消費率に基づいたアラームが自動生成されます。
ハンズオン完了後は以下の順序でリソースを削除してください。削除し忘れると継続的に費用が発生します。
ECS サービスを元に戻す(ADOT サイドカーなしのタスク定義に更新する)か、サービス・クラスターごと削除してください。ECS を引き続き使用する場合は元のタスク定義リビジョンにロールバックします。
CloudWatch コンソール → 「アラーム」→「すべてのアラーム」 で作成したアラームを選択して 「アクション」→「削除」 をクリックします。
myapp-high-fault-ratemyapp-high-latency-p99(作成した場合)CloudWatch コンソール → 「Application Signals」→「SLO」 で作成した SLO を選択して削除します。
myapp-availability-slomyapp-latency-sloCloudWatch コンソール → 「ダッシュボード」 で APM-Overview を選択して削除します。
SNS コンソール → 「トピック」 で apm-alert-topic を選択して削除します。
ECS コンソール → クラスター → サービスを選択して「更新」し、ADOT サイドカー追加前のリビジョンを指定して更新します。または ECS サービス・クラスターを削除します。
Systems Manager コンソール → 「パラメータストア」 で /otel/config を選択して削除します。
CloudWatch コンソール → 「ロググループ」 で以下を選択して削除します。
/ecs/otel-collector/aws/application-signals/dataこのハンズオンで追加したポリシー(CloudWatchAgentServerPolicy、AWSXRayDaemonWriteAccess、AmazonSSMReadOnlyAccess)を ECS タスク実行ロール・タスクロールからデタッチします。
/otel/config が削除された