Amazon CloudWatch Application Signalsを導入してなにが見えるか試してみた

記事タイトルとURLをコピーする

こんにちは。去年から体重管理をアプリで始めた小菅です。
数値をグラフ化して可視化してみると次のアクションを考える材料になりますよね。
ということで、Application Signalsの話をします。(無理やり)

皆さんのシステムでは「オブザーバビリティ(可観測性)」ってどこまで実現できていますか?

AWS Well-Architected Frameworkの運用上の優秀性の柱では、「Operate」のセクションにて以下のように述べられています。

Observability allows you to focus on meaningful data and understand your workload's interactions and output.

docs.aws.amazon.com

要するに、「必要なデータをちゃんと見て、システムがどう動いて何を返しているかを理解できるようにしましょう」ということです。
メトリクスを収集するだけでなく、正しく解釈し、ベースラインを定義し、逸脱を監視することが重要だと書かれています。

とはいえ、「オブザーバビリティを実現しましょう」と言われても、具体的にどうすればいいのか、AWSのサービスでどこまでできるのか、イメージが湧かない方も多いのではないでしょうか。

本ブログでは、Amazon CloudWatch Application Signalsを使って、コード変更なしでアプリケーションの可観測性を手に入れるまでの流れを紹介します。
「APMツールの導入を検討しているけど、AWSネイティブでどこまでできるの?」という方の参考になれば幸いです。

尚、コストについては以下を参照ください。

aws.amazon.com

Amazon CloudWatch Application Signalsとは

Amazon CloudWatch Application Signals(以下、Application Signals)は、AWSが提供するAPM(Application Performance Monitoring)機能です。

docs.aws.amazon.com

ざっくり言うと、以下のことがコード変更なしでできるようになります。

  • アプリケーションのレイテンシ、エラー率、リクエスト数の自動計測
  • サービス間の依存関係の自動検出と可視化
  • 個別リクエストの分散トレーシング
  • SLO(サービスレベル目標)の設定と監視

対応しているプラットフォームは以下の通りです(2026年4月時点)。

  • Amazon ECS(Fargate / EC2)
  • Amazon EKS
  • Amazon EC2
  • AWS Lambda

対応言語は Java、Python、.NET、Node.js、Go、PHP、Ruby です。

※対応プラットフォーム・言語は今後のアップデートで追加される可能性があります。最新情報は公式ドキュメントをご確認ください。

docs.aws.amazon.com

今回の検証構成

今回は以下のようなシンプルなマイクロサービス構成で検証しました。

検証 構成図

項目 内容
プラットフォーム Amazon ECS on AWS Fargate
フロントエンド Python(Flask)
バックエンド Python(Flask), DynamoDB
ロードバランサー Application Load Balancer
リージョン ap-northeast-1(東京)

フロントエンドがユーザーからのリクエストを受け取り、バックエンドのAPIを呼び出すという構成です。
バックエンドにはわざと遅いエンドポイントやエラーを返すエンドポイントも用意して、Application Signalsでどう見えるかを確認しました。

導入の仕組み

ゼロコード計装とは

Application Signalsの大きな特徴は、アプリケーションのコードを一切変更せずに導入できることです。
これは「ゼロコード計装(Zero-code Instrumentation)」と呼ばれる仕組みで実現されています。

裏側では、AWS Distro for OpenTelemetry(ADOT)というOpenTelemetryのAWSディストリビューションが使われています。

aws-otel.github.io

Pythonの場合、PYTHONPATH環境変数を設定することで、アプリケーション起動時にOpenTelemetryのライブラリが自動的に読み込まれます。

Amazon ECS上でのタスク定義の構成

Amazon ECS上でApplication Signalsを有効にするには、タスク定義に以下の3つのコンテナを配置します。

docs.aws.amazon.com

コンテナ 役割
initコンテナ ADOTのPython計装ライブラリを共有ボリュームにコピーして終了
Amazon CloudWatch Agentサイドカー アプリケーションからテレメトリデータを受信し、Amazon CloudWatchに送信
アプリケーションコンテナ 通常のアプリケーション。環境変数でADOTの計装ライブラリを読み込む

タスク定義の3コンテナ構成(initコンテナ・CloudWatch Agent・アプリケーション)

ポイントは、アプリケーションコンテナ自体には計装コードが含まれていないことです。
initコンテナが計装ライブラリを共有ボリュームに配置し、アプリケーションコンテナが環境変数経由でそれを読み込むという仕組みです。

データの流れ

アプリケーション
  → localhost:4316(Amazon CloudWatch Agentサイドカー)
  → Amazon CloudWatch(Application Signalsダッシュボード)

アプリケーションとAmazon CloudWatch Agentは同じタスク内のコンテナなので、localhostで通信できます。
Amazon CloudWatch Agentがデータを集約してAWSのバックエンドに送信します。

セットアップ手順

ここでは、Amazon ECS(Fargate)環境でApplication Signalsを有効にするまでの具体的な手順を紹介します。

1. Application Signalsの有効化

まず、Amazon CloudWatchコンソールでApplication Signalsを有効にします。

  1. AWSマネジメントコンソールで Amazon CloudWatch を開く
  2. 左メニューの Application Signalsサービス を選択
  3. サービスの検出を開始 をクリック
  4. チェックボックスを選択し、サービスの検出を開始 をクリック
  5. Application Signalsを有効にする をクリック

Application Signals 初回有効化画面
CloudWatch Application Signals を有効化にする

これにより、Application Signalsに必要なサービスリンクロールが自動作成されます。この操作はリージョンごとに1回だけ必要です。

docs.aws.amazon.com

2. IAMロールの準備

ECSのタスク定義にはIAMロールを2つ設定する箇所があります。Application Signalsを利用するために、以下の権限を追加します。

  • タスクロール: CloudWatchAgentServerPolicy
  • タスク実行ロール: AWS Systems Manager パラメータストアの読み取り権限(Amazon CloudWatch Agentの設定を secrets で渡すため)

3. Amazon CloudWatch Agentの設定

Amazon CloudWatch Agentの設定をAWS Systems Manager パラメータストアに保存します。

パラメータ名は公式ドキュメントの例に合わせて ecs-cwagent とします。

{
  "traces": {
    "traces_collected": {
      "application_signals": {}
    }
  },
  "logs": {
    "metrics_collected": {
      "application_signals": {}
    }
  }
}

application_signalstraces_collectedmetrics_collected の両方に指定するのがポイントです。
この設定は、次のステップのタスク定義でAmazon CloudWatch Agentサイドカーコンテナの CW_CONFIG_CONTENT に渡します。

4. タスク定義の作成

前述の3コンテナ構成でタスク定義を作成します。公式ドキュメントの手順に沿って、各コンテナの設定ポイントを説明します。

docs.aws.amazon.com

共有ボリュームの定義

タスク定義に opentelemetry-auto-instrumentation-python という名前のボリュームを定義します。initコンテナが計装ライブラリをこのボリュームにコピーし、アプリケーションコンテナがマウントして読み込む仕組みです。

Amazon CloudWatch Agentサイドカー

コンテナ名は ecs-cwagent とし、イメージは public.ecr.aws/cloudwatch-agent/cloudwatch-agent:latest を使用します。
Step 3でAWS Systems Manager パラメータストアに保存した設定を secretsCW_CONFIG_CONTENT 環境変数に渡します。essential: true に設定し、このコンテナが停止するとタスク全体が停止するようにします。

initコンテナ

コンテナ名は init とし、イメージは public.ecr.aws/aws-observability/adot-autoinstrumentation-python を使用します。
command で計装ライブラリを共有ボリュームにコピーして終了します。essential: false に設定し、コピー完了後にコンテナが終了してもタスクに影響しないようにします。

アプリケーションコンテナ

通常のアプリケーションコンテナに、共有ボリュームのマウントと dependsOn を追加します。
dependsOn では、initコンテナに condition: SUCCESS(コピー完了後に起動)、Amazon CloudWatch Agentに condition: START(起動後に起動)を設定します。

加えて、Application Signalsに必要な環境変数を設定します。主な環境変数は以下のとおりです(Pythonの場合)。

タスク定義 — アプリケーションコンテナの環境変数

環境変数 値の例 説明
OTEL_RESOURCE_ATTRIBUTES service.name=frontend-api Application Signalsに表示されるサービス名。未設定だとUnknownServiceになる
OTEL_AWS_APPLICATION_SIGNALS_ENABLED true Application Signalsの有効化
OTEL_METRICS_EXPORTER none 他のメトリクスエクスポーターを無効化
OTEL_LOGS_EXPORTER none 他のログエクスポーターを無効化
OTEL_EXPORTER_OTLP_PROTOCOL http/protobuf OTLP/HTTPでメトリクスとトレースを送信
OTEL_AWS_APPLICATION_SIGNALS_EXPORTER_ENDPOINT http://localhost:4316/v1/metrics CW Agentサイドカーへのメトリクス送信先
OTEL_EXPORTER_OTLP_TRACES_ENDPOINT http://localhost:4316/v1/traces CW Agentサイドカーへのトレース送信先
OTEL_TRACES_SAMPLER xray X-Rayサンプリングルールを使用
OTEL_TRACES_SAMPLER_ARG endpoint=http://localhost:2000 X-Rayサンプラーのエンドポイント
OTEL_PROPAGATORS tracecontext,baggage,b3,xray トレースコンテキストの伝播方式
OTEL_PYTHON_DISTRO aws_distro AWS用のOpenTelemetryディストリビューション
OTEL_PYTHON_CONFIGURATOR aws_configurator AWS用のOpenTelemetry設定
PYTHONPATH /otel-auto-instrumentation-python/opentelemetry/instrumentation/auto_instrumentation:/app:/otel-auto-instrumentation-python 計装ライブラリの読み込みパス。/appの部分はアプリケーションの作業ディレクトリに置き換える

環境変数が多く見えますが、ほとんどは公式ドキュメントのサンプルをそのままコピーすれば大丈夫です。自分で考えて設定するのは OTEL_RESOURCE_ATTRIBUTESservice.name(サービス名)と PYTHONPATH のアプリケーションパス部分くらいです。

5. ECSサービスの作成・更新

タスク定義を指定してECSサービスを作成(または既存サービスを更新)すれば、デプロイ完了です。

タスクが起動すると、initコンテナ → CW Agent → アプリケーションの順で起動し、数分後にはApplication Signalsのコンソールにサービスが表示されます。

初回のデータ反映には10分ほどかかります。「設定したのにデータが出ない!」と焦らず、少し待ってみてください。そうです、私は焦りました。

Amazon CloudWatch Application Signalsで何が見える?

ここからが本題です。実際にApplication Signalsを有効にすると、Amazon CloudWatchのコンソールでどんな情報が見えるようになるのかをご紹介します。

1. サービス一覧

Amazon CloudWatchコンソールの「Application Signals」→「サービス」を開くと、以下の情報が表示されます。

Application Signals にサービスが表示された状態

ここからサービスをクリックすると、サービスごとの詳細画面に遷移します。

サービス一覧には、計装(インストルメンテーション)済みのサービスだけでなく、通信先として自動検出されたサービスも表示されます。
今回の構成では、計装済みの frontend-apibackend-api に加えて、ALBの appsignals-alb やリクエスト元の traffic-gen も表示されました。計装していないサービスには「インストルメンテーションを未実施」と表示されます。

2. サービス詳細 — 概要とサービスオペレーション

サービス一覧から frontend-api をクリックすると、サービス詳細画面に遷移します。

frontend-api サービス詳細 — 概要タブ

「概要」タブでは、サービス全体のリクエスト数・可用性・レイテンシ・障害(5xx)・エラー(4xx)が確認できます。
可用性の数値自体がリンクになっていて、クリックすると「サービスオペレーション」タブに遷移します。

frontend-api サービス詳細 — サービスオペレーションタブ

「サービスオペレーション」タブでは、オペレーションごとの障害率やレイテンシが表示されます。
障害率でソートすると、どのオペレーションが問題を起こしているかが一目瞭然です。今回の検証では GET /unreliable がダントツでした。

3. サービス詳細 — 依存関係

同じサービス詳細画面の「依存関係」タブでは、そのサービスが呼び出している外部サービスやAWSリソースが表示されます。

frontend-api サービス詳細 — 依存関係タブ

レイテンシ・リクエスト数・障害率・エラー率・可用性といったメトリクスも依存先ごとに確認できます。

backend-api サービス詳細 — 依存関係タブ

backend-api の依存関係タブでは、AWS::DynamoDBGetItemPutItem のオペレーション別に表示されました。
APIレベルでどの操作に問題があるのかまで把握できるのは便利です。

4. アプリケーションマップ

左メニューの「アプリケーションマップ」を開くと、サービス間の関係がビジュアルに表示されます。

アプリケーションマップ(frontend-apiをクリックした状態)

frontend-api をクリックすると、「Health」タブと「相関するトレース」タブが表示されます。
「Health」タブでは正常性・変更・オペレーショナル監査・メトリクスが確認できます。

5. トレース

Amazon CloudWatchの左メニューにある「トレース」を開くと、個別のトレースが表形式で一覧表示されます。

トレース 画面

各トレースには一意のIDが付与されており、トレースステータス・タイムスタンプ・レスポンスコード・応答時間・所要時間・HTTPメソッド・URLアドレスが確認できます。

6. トレースマップ

左メニューの「トレースマップ」を開くと、クライアントを起点としたサービス間の呼び出しフローが表示されます。

トレースマップ 画面

今回の構成では、クライアント → frontend-apibackend-apiappsignals-handson(Amazon DynamoDB テーブル)という流れが確認できました。
各ノードをクリックすると「メトリクス」「アラート」「応答時間分布」の3つのタブがあり、レイテンシ・リクエスト数・パーセントのメトリクスや、応答時間の分布(x軸: 秒数、y軸: パーセント)が確認できます。

おわりに

Application Signalsを使ってみて、「コード変更なしでここまで見えるようになるのか」というのが率直な感想です。

特に以下の点が印象的でした。

  • アプリケーションコードの変更が不要: タスク定義の変更だけで導入できる。既存のコードに手を入れる必要がない
  • 依存関係の自動検出: 実際の通信から依存関係を検出してくれる
  • エンドポイント単位の可視化: どのAPIが遅いのか、どのAPIでエラーが多いのかが一目瞭然

AWSネイティブの機能なので既存のAWSアカウント内で完結できるのは個人的に大きなメリットだと感じました。

「オブザーバビリティを実現したいけど、まずはAWSの機能でどこまでできるか試してみたい」という方には、Application Signalsは良い選択肢になると思います。

今回のブログではApplication Signalsの機能をすべて網羅できているわけではありません。SLO設定やRUM、Synthetics canaryとの連携など、まだまだ紹介しきれていない機能があります。
気になる方はぜひご自身の環境で試してみてください。

小菅 信幸(執筆記事の一覧)

仙台在住/サウナをこよなく愛するエンジニア
2024 Japan AWS All Certifications Engineers
2025 Japan All AWS Certifications Engineers