AWS

Application Signalsの導入手順|ECS・EKS・EC2・Lambda別の有効化設定と表示されないときの確認

Application Signalsの導入手順|ECS・EKS・EC2・Lambda別の有効化設定と表示されないときの確認

Application Signalsは、CloudWatchに組み込まれたAWSのAPM(アプリケーション性能監視)機能です。AWS Distro for OpenTelemetry(ADOT)の自動計装でアプリケーションのリクエストを拾い、サービスごとのレイテンシー・障害・エラーとサービス間の依存関係をCloudWatchに表示します。コードを書き換える必要はありませんが、どこまで自動でやってくれるかは実行基盤で大きく違います。EKSならアドオン1つでほぼ終わる一方、ECSとEC2ではCloudWatchエージェントとADOTを自分で組み込み、サービス名も自分で指定します。

この記事では、ECS・EKS・EC2・Lambdaそれぞれの有効化手順を、タスク定義・Pod注釈・エージェント設定の実際の記述で示し、最後にデータが表示されないときの確認順をまとめます。設定値はAWS公式ドキュメント「Enable your applications on Amazon ECS」ほか各プラットフォームの有効化ページ(2026年10月時点)に基づきます。料金の試算とSLOの設計はCloudWatch Application Signalsの料金・SLO設計の解説で扱っています。

まとめ|Application Signalsを有効化するための要点

  • ECS・EKS・EC2・Kubernetesでは、アカウントでの初回有効化(サービスリンクロールの作成)、CloudWatchエージェントのapplication_signals設定、ADOTによる計装の3段階が要る。Lambdaはエージェントを使わず、レイヤーが計装を担う。
  • EKSはCloudWatch Observabilityアドオンを入れて、Podか名前空間に注釈を付ければ計装まで終わる。v5.0.0以降のアドオンは既定で自動監視が有効になるため、既存のOpenTelemetry計装があるクラスターでは先に設定を確認する。
  • ECSはサイドカー方式かデーモン方式を選ぶ。Fargateならサイドカー方式しか選べない。サービス名はOTEL_RESOURCE_ATTRIBUTESのservice.nameで自分で付け、付け忘れるとUnknownServiceと表示される。
  • EC2とオンプレミスは、2023年11月30日以降に公開されたCloudWatchエージェントとADOTエージェントを手で入れる。オンプレミスはIAMユーザーのアクセスキーで認証する。
  • Lambdaはコンソールのチェックボックス1つで有効化できる。データが出ないときは、最後の変更から15分待ってから、検出の有効化・エージェントの稼働・権限・計装の順に確認する。

Application Signalsの導入に共通する3段階と基盤ごとの違い

ECS・EKS・EC2・Kubernetesでは、手順の見た目は違っても中身は次の3段階に分かれます。EKSのアドオンは、このうち2と3をまとめて肩代わりしているだけです。Lambdaは例外で、1のあとはCloudWatchエージェントを置かず、ADOTを含むLambdaレイヤーが計装と送信を担います。

  1. アカウントでの初回有効化:リージョンごとに1回。サービスリンクロールAWSServiceRoleForCloudWatchApplicationSignalsが作られ、X-Rayのサービスグラフ、CloudWatch Logsのクエリ、CloudWatchメトリクスの読み取りなどの権限がApplication Signalsに渡る。
  2. CloudWatchエージェントの設定:アプリケーションからOTLPでメトリクスとトレースを受ける窓口。ポート4316で受け、2000番はX-Rayのサンプリング設定の取得に使う。
  3. ADOTによる計装:言語ごとのADOTエージェントをアプリケーションに読み込ませ、環境変数で送信先とサービス名を指定する。

1はコンソールの「Application Signals」→「サービス」→「サービスの検出を開始」でも実行できますが、CLIなら次の1行です。CloudFormationではAWS::ApplicationSignals::Discoveryリソースが同じ役割を持ちます。

aws application-signals start-discovery --region ap-northeast-1

2のエージェント設定は、ECS・EC2・Kubernetesのいずれでも次のJSONが最小構成です。tracesとlogsの両方にapplication_signalsを書くのがポイントで、片方だけだとトレースかメトリクスのどちらかが欠けます。

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

基盤ごとの違いは次の表のとおりです。サービス名を自動で拾ってくれるのはEKS(アドオン経由)とLambdaだけで、ECS・EC2・EKS以外のKubernetesはカスタムセットアップ扱いになり、指定した名前がそのままダッシュボードに出ます。

基盤 エージェントの置き方 計装の入れ方 サービス名
EKS アドオンがDaemonSetで配置 Pod・名前空間の注釈 自動
ECS(Fargate) タスクごとのサイドカー initコンテナ+環境変数 手動指定
ECS(EC2起動タイプ) サイドカーかデーモン initコンテナ+環境変数 手動指定
EC2・オンプレミス ホストにインストール 起動コマンド+環境変数 手動指定
EKS以外のKubernetes Helmチャート Pod・名前空間の注釈 手動指定
Lambda 不要 Lambdaレイヤー 関数名

計装できる言語は、AWSのサポート表でJava(JVM 8・11・17・21・23・25)、Python(3.10〜3.14)、Node.js(18・20・22・24)、.NET(8・9・10と.NET Framework 4.6.2以降)です。Go・PHP・RubyはADOTの自動計装が無く、標準のOpenTelemetry SDKで送る構成になります。この場合の課金上の注意はApplication Signalsの料金・対応言語の解説を参照してください。

ECSでの有効化|サイドカー方式とデーモン方式

ECSでは、CloudWatchエージェントをどこで動かすかで2つの方式があります。どちらもADOTの計装はアプリケーションのタスク定義側に書くので、違うのはエージェントの置き場所と、アプリケーションから見た送信先アドレスです。

サイドカーとデーモンを分ける判断基準

観点 サイドカー方式 デーモン方式
Fargate 対応 非対応
EC2起動タイプ 対応 対応
ネットワークモード awsvpcのみ host・bridge・awsvpc
エージェントの設定回数 タスク定義ごと クラスターで1回
送信先アドレス 常にlocalhost hostモード以外はインスタンスのIP

Fargateならサイドカー方式一択です。EC2起動タイプでも、awsvpcのタスクならサイドカー方式を勧めます。bridgeのタスクはサイドカー方式に対応していないため、awsvpcへ移すか、デーモン方式を選ぶかのどちらかになります。デーモン方式はエージェントが1か所で済む代わりに、bridgeとawsvpcではアプリケーションの環境変数にコンテナインスタンスのプライベートIPを書く必要があり、インスタンスが入れ替わるたびに値が変わる問題を自分で解決しなければなりません。デーモン方式が素直に使えるのは、アプリケーションもhostネットワークモードで動かしている場合です。

サイドカー方式のタスク定義(Javaの例)

まず、エージェント設定のJSONをSSMパラメータストアに置きます。タスク定義からはsecretsのvalueFromで読み込むため、タスク実行ロールにパラメータの読み取り権限(ssm:GetParameters)が必要です。タスクロールには、アプリケーション自身の権限に加えてCloudWatchAgentServerPolicyを付けます。

aws ssm put-parameter \
  --name "ecs-cwagent" \
  --type "String" \
  --value "`cat /tmp/ecs-cwagent.json`" \
  --region ap-northeast-1

タスク定義には、共有ボリューム、エージェントのサイドカー、ADOTのjarをコピーするinitコンテナ、アプリケーションの環境変数の4つを足します。公式手順をJavaアプリケーション1つの形にまとめると次のとおりです。イメージのタグは、ECR Publicのcloudwatch-agentとadot-autoinstrumentation-javaで最新を確認して固定してください(2026年10月2日時点のGitHubリリースはADOT Java v2.31.0、CloudWatchエージェント1.300073.0)。

{
  "family": "orders-api",
  "networkMode": "awsvpc",
  "requiresCompatibilities": ["FARGATE"],
  "volumes": [{ "name": "opentelemetry-auto-instrumentation" }],
  "containerDefinitions": [
    {
      "name": "init",
      "image": "public.ecr.aws/aws-observability/adot-autoinstrumentation-java:v2.31.0",
      "essential": false,
      "command": ["cp", "/javaagent.jar", "/otel-auto-instrumentation/javaagent.jar"],
      "mountPoints": [{
        "sourceVolume": "opentelemetry-auto-instrumentation",
        "containerPath": "/otel-auto-instrumentation",
        "readOnly": false
      }]
    },
    {
      "name": "ecs-cwagent",
      "image": "public.ecr.aws/cloudwatch-agent/cloudwatch-agent:latest",
      "essential": false,
      "secrets": [{ "name": "CW_CONFIG_CONTENT", "valueFrom": "ecs-cwagent" }]
    },
    {
      "name": "app",
      "image": "123456789012.dkr.ecr.ap-northeast-1.amazonaws.com/orders-api:1.4.0",
      "dependsOn": [{ "containerName": "init", "condition": "SUCCESS" }],
      "mountPoints": [{
        "sourceVolume": "opentelemetry-auto-instrumentation",
        "containerPath": "/otel-auto-instrumentation",
        "readOnly": false
      }],
      "environment": [
        { "name": "OTEL_RESOURCE_ATTRIBUTES", "value": "service.name=orders-api,deployment.environment=prod" },
        { "name": "OTEL_AWS_APPLICATION_SIGNALS_ENABLED", "value": "true" },
        { "name": "OTEL_METRICS_EXPORTER", "value": "none" },
        { "name": "OTEL_LOGS_EXPORTER", "value": "none" },
        { "name": "OTEL_EXPORTER_OTLP_PROTOCOL", "value": "http/protobuf" },
        { "name": "OTEL_AWS_APPLICATION_SIGNALS_EXPORTER_ENDPOINT", "value": "http://localhost:4316/v1/metrics" },
        { "name": "OTEL_EXPORTER_OTLP_TRACES_ENDPOINT", "value": "http://localhost:4316/v1/traces" },
        { "name": "OTEL_TRACES_SAMPLER", "value": "xray" },
        { "name": "OTEL_PROPAGATORS", "value": "tracecontext,baggage,b3,xray" },
        { "name": "JAVA_TOOL_OPTIONS", "value": " -javaagent:/otel-auto-instrumentation/javaagent.jar" }
      ]
    }
  ]
}

見落としやすいのは2点です。dependsOnのSUCCESS条件が無いと、jarのコピーが終わる前にアプリケーションが起動して-javaagentの読み込みに失敗します。deployment.environmentを省くとECSクラスター名が環境名として使われるので、同じクラスターにステージングと本番を同居させているなら明示してください。実際のタスク定義では、ここで省いたcpu・memory・executionRoleArn・taskRoleArn・ログ設定も必要です。

Python・Node.js・.NETで変わる設定

言語が変わると、initコンテナのイメージとコピー元、アプリケーションにADOTを読み込ませる環境変数が変わります。送信先の4316番とOTEL_AWS_APPLICATION_SIGNALS_ENABLED=trueは共通です。

言語 initのイメージ コピー元 読み込ませる環境変数
Java adot-autoinstrumentation-java /javaagent.jar JAVA_TOOL_OPTIONS
Python adot-autoinstrumentation-python /autoinstrumentation/. PYTHONPATH
Node.js adot-autoinstrumentation-node /autoinstrumentation/. NODE_OPTIONS
.NET adot-autoinstrumentation-dotnet autoinstrumentation/. CORECLR_*・DOTNET_*

Pythonは追加の変数が多く、OTEL_PYTHON_DISTRO=aws_distroとOTEL_PYTHON_CONFIGURATOR=aws_configuratorでADOTの設定を使わせ、PYTHONPATHにはADOTの自動計装ディレクトリとアプリケーションの作業ディレクトリの両方を並べます。作業ディレクトリを入れ忘れると、計装以前にアプリケーションが起動しないことがあり、公式のトラブルシューティングにも既知の問題として載っています。Djangoは--noreloadとDJANGO_SETTINGS_MODULEも必要です。

PYTHONPATH=/otel-auto-instrumentation-python/opentelemetry/instrumentation/auto_instrumentation:/app:/otel-auto-instrumentation-python
OTEL_PYTHON_DISTRO=aws_distro
OTEL_PYTHON_CONFIGURATOR=aws_configurator
OTEL_TRACES_SAMPLER=xray
OTEL_TRACES_SAMPLER_ARG=endpoint=http://localhost:2000

Node.jsはNODE_OPTIONS=--require /otel-auto-instrumentation-node/autoinstrumentation.jsで読み込みます。この方法はCommonJS前提で、ESM形式のアプリケーションは別手順になります(後述のEKSの節と同じ制約)。.NETはプロファイラーの仕組みを使うため、CORECLR_ENABLE_PROFILING=1、CORECLR_PROFILER(CLSID)、CORECLR_PROFILER_PATH、DOTNET_STARTUP_HOOKSなどを公式手順どおりに並べます。プロファイラーのパスはLinuxならlinux-x64/OpenTelemetry.AutoInstrumentation.Native.so、Windows Serverならwin-x64/OpenTelemetry.AutoInstrumentation.Native.dllで、Windowsコンテナではinitのコマンドも変わります。

デーモン方式でエンドポイントを書き換える箇所

デーモン方式では、エージェント用のタスク定義(公式例のファミリー名はecs-cwagent-daemon、bridgeモード)を作り、ECSサービスのスケジューリング戦略をDAEMONにしてクラスターに1回だけ配置します。エージェントはホストの4316番と2000番を使うため、同じホストでこの2つのポートを使う別サービスがあると衝突します。

アプリケーション側の変更は送信先だけです。hostモードならサイドカー方式と同じlocalhostのまま動きます。bridgeかawsvpcの場合は、次の3つの変数のlocalhostを、インスタンスメタデータサービス(IMDS)から取ったコンテナインスタンスのプライベートIPに置き換えます。

OTEL_AWS_APPLICATION_SIGNALS_EXPORTER_ENDPOINT=http://10.0.12.34:4316/v1/metrics
OTEL_EXPORTER_OTLP_TRACES_ENDPOINT=http://10.0.12.34:4316/v1/traces
OTEL_TRACES_SAMPLER_ARG=endpoint=http://10.0.12.34:2000

タスク定義の環境変数は静的な値なので、インスタンスごとに違うIPを入れるにはエントリポイントでIMDSを引いて書き換えるなどの工夫が要ります。この手間を許容できないなら、サイドカー方式を選ぶ方が運用は単純です。

EKSでの有効化|CloudWatch Observabilityアドオンと注釈

EKSでは、Amazon CloudWatch Observability EKSアドオンがCloudWatchエージェントとADOTの注入の仕組みをまとめて入れます。このアドオンはContainer Insights(拡張オブザーバビリティ)も同時に有効にします。アプリケーション側で書くのは注釈だけです。

アドオンの導入とIAM権限

CloudWatchコンソールの「Application Signals」で「EKS」を選び、対象クラスターを指定すると、アドオンが無ければEKSコンソールでの追加に誘導されます。IAMロールに「ノードから継承」を選んだ場合は、ワーカーノードのロールに次の2つのポリシーを付けます。

aws iam attach-role-policy --role-name my-worker-node-role \
  --policy-arn arn:aws:iam::aws:policy/CloudWatchAgentServerPolicy
aws iam attach-role-policy --role-name my-worker-node-role \
  --policy-arn arn:aws:iam::aws:policy/AWSXRayWriteOnlyAccess

ノードロールに権限を付けると、PodからIMDSへのアクセスを制限していない限り、そのノードで動くPodが同じ権限を使えてしまいます。アドオンv3.1.0以降では、公式がEKS Pod Identityを推奨しており、cloudwatch-agentサービスアカウントだけにCloudWatchAgentServerPolicy付きのロールを関連付けられます(IRSAも利用可)。なお、WindowsノードではContainer Insightsは動きますが、Application Signalsは対応していません。

Pod注釈と名前空間注釈の書き方

計装は、DeploymentのPodTemplateか、名前空間のメタデータに注釈を付けて有効にします。注釈名は言語ごとに分かれています。

# 抜粋(selector・replicas などは省略)
apiVersion: apps/v1
kind: Deployment
metadata:
  name: orders-api
spec:
  template:
    metadata:
      annotations:
        instrumentation.opentelemetry.io/inject-java: "true"
        # Python: inject-python / Node.js: inject-nodejs / .NET: inject-dotnet
    spec:
      containers:
        - name: orders-api
          image: 123456789012.dkr.ecr.ap-northeast-1.amazonaws.com/orders-api:1.4.0

名前空間に付けると、その名前空間の既存と今後のワークロードがすべて対象になります。注釈は次にPodが作られるときに効くので、適用後はkubectl rollout restart deployment -n <名前空間>で再起動します。コンソールの「Console」方式でワークロードを選んだ場合は即座にPodが再起動されるため、本番クラスターでは注釈方式で再起動のタイミングを自分で決める方が安全です。.NETをAlpine Linuxベースのイメージで動かすときは、注釈instrumentation.opentelemetry.io/otel-dotnet-auto-runtime: "linux-musl-x64"を足します。

アドオンv5.0.0以降の自動監視と無効化の設定

アドオン(とHelmチャート)のv5.0.0から、OpenTelemetryベースのAPMがApplication Signals経由で既定で有効になりました。設定のmanager.applicationSignals.autoMonitorにあるmonitorAllServicesの既定値はtrueで、Kubernetes Serviceに紐づくDeployment・DaemonSet・StatefulSetが、新規作成時か次の再起動時に自動で計装されます。kube-systemとamazon-cloudwatchの名前空間は既定で除外されます。

注意したいのは、既にDatadogやNew Relic、自前のOpenTelemetry Collectorで計装しているクラスターでアドオンを更新すると、次の再起動でADOTが注入される点です。公式ドキュメントも、OpenTelemetryベースのAPMを使っている場合は既存の構成に影響すると明記しています。さらに、アプリケーションのコード内に直書きしたOTLPの送信先はアドオンに上書きされることがあり、メトリクスとトレースが本来の送信先に届かなくなります(コンテナの環境変数やenvFromのConfigMapで指定した送信先は上書きされません)。アドオンを更新する前に、詳細設定で次のように無効化しておきます。

{
  "manager": {
    "applicationSignals": {
      "autoMonitor": {
        "monitorAllServices": false
      }
    }
  }
}

逆に対象を絞って自動化したい場合は、言語と名前空間を指定します。次はpet-warehouse名前空間のJavaワークロードだけを自動計装し、設定保存時にPodを再起動する例です(restartPodsの既定はfalse)。monitorAllServicesは既定でtrueなので、明示的にfalseにしないと他のサービスも対象に残ります。除外したいワークロードはexcludeに名前空間/Deployment名の形式で書き、除外は対象指定より優先されます。

manager:
  applicationSignals:
    autoMonitor:
      monitorAllServices: false
      restartPods: true
      customSelector:
        java:
          namespaces: ["pet-warehouse"]

2026年10月2日時点のHelmチャートの最新はamazon-cloudwatch-observability 6.7.0(2026年9月21日公開)です。

Node.jsのESMアプリケーションの手動計装

ESM形式のNode.jsアプリケーションは、コンソールでの有効化も注釈も効きません。@aws/aws-distro-opentelemetry-node-autoinstrumentationを依存関係に入れ、DockerfileでApplication Signals用の環境変数を設定してイメージを作り直します。このときinject-nodejsの注釈は付けたままにしないよう、公式手順でも注意されています。送信先はクラスター内のエージェントのサービス名cloudwatch-agent.amazon-cloudwatch:4316です。

EKS以外のKubernetesへのHelm導入

EKS以外のKubernetes(EC2上の自前クラスターやオンプレミス)では、アドオンの代わりにHelmチャートでエージェントのオペレーターを入れ、その後は注釈で計装します。clusterNameに指定した名前がダッシュボードに表示されます。オンプレミスの場合は、CloudWatchAgentServerPolicyを付けたIAMユーザーのアクセスキーをクラスターに渡す手順が加わります。

helm repo add aws-observability https://aws-observability.github.io/helm-charts
helm install amazon-cloudwatch-operator aws-observability/amazon-cloudwatch-observability \
  --namespace amazon-cloudwatch --create-namespace \
  --set region=ap-northeast-1 \
  --set clusterName=onprem-k8s-01

EC2・オンプレミスでの有効化|CloudWatchエージェントとADOTの手動導入

EC2とオンプレミスのサーバーでは、CloudWatchエージェントをホストに入れ、アプリケーションの起動コマンドにADOTを組み込みます。Application Signalsに対応するのは2023年11月30日以降に公開されたエージェントなので、古いエージェントが入っているホストは更新が先です。

エージェントの設定は前述の最小構成のJSONを/opt/aws/amazon-cloudwatch-agent/etc/amazon-cloudwatch-agent.jsonに置き、インスタンスのIAMロールにCloudWatchAgentServerPolicyを付けてから起動します。-cの値にはfile:の接頭辞が必須です。

sudo /opt/aws/amazon-cloudwatch-agent/bin/amazon-cloudwatch-agent-ctl \
  -a fetch-config -m ec2 -s \
  -c file:/opt/aws/amazon-cloudwatch-agent/etc/amazon-cloudwatch-agent.json

JavaはADOT Javaのリリースからaws-opentelemetry-agent.jarを取得し、環境変数を付けて起動します。

JAVA_TOOL_OPTIONS=" -javaagent:/opt/adot/aws-opentelemetry-agent.jar" \
OTEL_METRICS_EXPORTER=none \
OTEL_LOGS_EXPORTER=none \
OTEL_AWS_APPLICATION_SIGNALS_ENABLED=true \
OTEL_AWS_APPLICATION_SIGNALS_EXPORTER_ENDPOINT=http://localhost:4316/v1/metrics \
OTEL_EXPORTER_OTLP_PROTOCOL=http/protobuf \
OTEL_EXPORTER_OTLP_TRACES_ENDPOINT=http://localhost:4316/v1/traces \
OTEL_RESOURCE_ATTRIBUTES="service.name=billing-batch,deployment.environment=prod" \
java -jar billing-batch.jar

Pythonはpip install aws-opentelemetry-distro(2026年10月2日時点のPyPI最新は0.20.0、Python 3.10以上)で入れ、opentelemetry-instrument python app.pyの形で起動します。環境変数はECSのPythonと同じくOTEL_PYTHON_DISTROとOTEL_PYTHON_CONFIGURATORが要ります。

オンプレミスのサーバーにはインスタンスロールが無いため、CloudWatchAgentServerPolicyを付けたIAMユーザーを作り、そのアクセスキーをaws configureでホストに設定します。長期のアクセスキーを置くことになるので、キーのローテーションと権限をこのポリシーだけに絞る運用を前提にしてください。

Lambdaでの有効化|コンソール設定と手動・IaCで必要な3項目

Lambdaはエージェントを置かず、ADOTを含むAWS Lambda Layer for OpenTelemetryが計装を担います。Lambdaコンソールなら、関数の「設定」→「モニタリングおよび運用ツール」→「編集」で、Application Signalsによるトレースと標準メトリクスの自動収集にチェックを入れて保存するだけです。CloudWatchコンソールの「Application Signals」から「Lambda」を選び、複数の関数をまとめて有効にすることもできます。

手動やIaCで設定する場合は、レイヤーの追加、環境変数AWS_LAMBDA_EXEC_WRAPPER=/opt/otel-instrument、実行ロールへのCloudWatchLambdaApplicationSignalsExecutionRolePolicyの付与の3点です。既定の計装範囲を広げる環境変数や、コンテナイメージでデプロイした関数にレイヤーの中身を取り込む手順は、Application SignalsのLambda最小構成の解説に載せています。

CDKで有効化するときの注意|ECS用の構成はexperimental

アカウントでの初回有効化は、安定版のaws-cdk-libに含まれるL1リソースCfnDiscoveryで書けます。

import { aws_applicationsignals as applicationsignals } from 'aws-cdk-lib';

new applicationsignals.CfnDiscovery(this, 'ApplicationSignalsDiscovery', {});

ECSのタスク定義にサイドカーとinitコンテナを組み込む作業は、別パッケージ@aws-cdk/aws-applicationsignals-alphaのApplicationSignalsIntegrationがまとめて引き受けます。ただし、このパッケージはREADMEで「experimental」と明示され、将来の版で後方互換の無い変更や削除がありうるとされています(2026年10月2日時点の最新は2.272.0-alpha.0)。

もう一つの落とし穴が、ADOTの版を指定する列挙です。ソースに定義されている版はJavaがV2_10_0、PythonがV0_9_0、Node.jsがV0_6_0、.NETがV1_7_0までで、ADOTの現行版(Java v2.31.0、Python v0.20.0)からかなり遅れています。列挙をそのまま使うと古い計装エージェントで動かすことになります。コンストラクタは公開されているので、版を直接指定できます。指定する版はADOTのリリースノートで変更点を確認してから固定してください。

import * as appsignals from '@aws-cdk/aws-applicationsignals-alpha';

new appsignals.ApplicationSignalsIntegration(this, 'AppSignals', {
  taskDefinition: fargateTaskDefinition,
  serviceName: 'orders-api',
  instrumentation: {
    sdkVersion: new appsignals.JavaInstrumentationVersion(
      appsignals.JavaInstrumentationVersion.IMAGE_REPO,
      'v2.31.0',
      appsignals.JavaInstrumentationVersion.DEFAULT_MEMORY_LIMIT_MIB,
    ),
  },
  cloudWatchAgentSidecar: {
    containerName: 'cloudwatch-agent',
    enableLogging: true,
    cpu: 256,
    memoryLimitMiB: 512,
  },
});

experimentalのパッケージをCDKのバージョン更新のたびに追いかける体制が無いなら、本番ではタスク定義をL1や素のJSONで書き、前述の4要素を自分で管理する方を選びます。

データが表示されないときの確認順

有効化してもダッシュボードにサービスが出ない場合、公式のトラブルシューティングは最後の変更から15分待ってから調べるよう求めています。それを過ぎても出ないときは、外側から順に次を確認します。

15分待っても何も出ないときの確認項目

  1. 検出の有効化:CloudWatchコンソールの「Application Signals」→「サービス」で、手順1が「完了」になっているか。未完了なら「サービスの検出を開始」を実行すると、5分ほどでデータが流れ始める。リージョンごとに必要。
  2. エージェントの稼働:EKSならkubectl -n amazon-cloudwatch get podsで全PodがRunningか。エージェント設定のagentに"debug": trueを足して再起動し、エラーを探す。
  3. 権限:エージェントのログにAccess Deniedがあれば、導入後にロールのポリシーが外されていないか確認する。
  4. 計装の注入:EKSでは注釈の値が"true"か、initコンテナがReadyになっているか。ECSではinitコンテナがSUCCESSで終了しているか。
  5. 送信の失敗:アプリケーションのログにFailed to exportが出ていないか。JavaはOTEL_JAVAAGENT_DEBUG=true、PythonはOTEL_PYTHON_LOG_LEVEL=debugで詳細ログを出せる。エージェント側のスロットリングのログも確認する。

UnknownServiceやUnknownRemoteServiceの表示原因

サービス一覧にUnknownServiceが出るのは、OTEL_SERVICE_NAMEもOTEL_RESOURCE_ATTRIBUTESのservice.nameも設定されていないときです。ECSとEC2はサービス名を自動で拾わないので、まずここを疑います。UnknownOperationはリモート呼び出しを起こした操作名が特定できないか、操作名にIDなど値の種類が多すぎる文字列が含まれる場合に出ます。依存先がUnknownRemoteServiceになるのは、計装ライブラリが呼び出し先の種類を判別できない場合で、デプロイの時刻と重なっていないかも確認します。

Gunicorn・uWSGI・Uvicornのワーカーからの未送信

プリフォーク型のサーバーでは、親プロセスで初期化したOpenTelemetry SDKのバックグラウンドスレッドがフォーク後のワーカーに引き継がれず、ワーカーからデータが送られません。対処は2段階で、ワーカー側で計装を初期化したうえで、環境変数OTEL_AWS_PYTHON_DEFER_TO_WORKERS_ENABLED=trueで親プロセスの初期化を飛ばします。Gunicornなら設定ファイルのpost_forkフックで初期化します。

# gunicorn.conf.py
def post_fork(server, worker):
    from opentelemetry.instrumentation.auto_instrumentation import sitecustomize

uWSGIはenable-threads = trueとlazy-apps = trueとimport = opentelemetry.instrumentation.auto_instrumentation.sitecustomize、複数ワーカーのUvicornはアプリケーションをimportする前にinitialize()を呼びます。この対処にはADOT PythonとEKSアドオンの最新版が前提です。

よくある質問

Application Signalsとは何ですか?

CloudWatchのAPM機能です。ADOTでアプリケーションを自動計装し、サービスごとのレイテンシー・障害・エラーの指標、サービス間の依存関係、SLOをCloudWatch上で扱えます。料金とSLOの設計はCloudWatch Application Signalsの解説で詳しく説明しています。

ECSのFargateでもApplication Signalsは使えますか?

使えます。ただしサイドカー方式に限られ、ネットワークモードはawsvpcです。デーモン方式はFargateに対応していません。

Lambdaでは何を設定すればApplication Signalsが有効になりますか?

Lambdaコンソールの「モニタリングおよび運用ツール」でApplication Signalsの自動収集にチェックを入れれば有効になります。手動ならレイヤーの追加、AWS_LAMBDA_EXEC_WRAPPER=/opt/otel-instrument、実行ロールへのCloudWatchLambdaApplicationSignalsExecutionRolePolicyの付与の3点です。

EKSで既存のOpenTelemetry計装と共存できますか?

アドオンv5.0.0以降は自動監視が既定で有効なため、そのまま更新すると次の再起動でADOTが注入されます。既存の計装を残したいワークロードは、autoMonitorのmonitorAllServicesをfalseにするか、excludeで外してから更新してください。

Application SignalsでGoやRubyのアプリケーションは計装できますか?

ADOTの自動計装はJava・Python・Node.js・.NETの4言語です。Go・PHP・Rubyは標準のOpenTelemetry SDKで計装し、Transaction Searchを有効にしてトレースを送る構成になります。

関連記事

お気に入りに入れた記事の一覧

この記事は以下の記事からリンクされています

資料請求

今日のトレンド記事 直近 24 時間で、いつもより多く読まれている記事

  1. 2026.07.21 テックブログ Apache Tomcatの脆弱性一覧【2026年10月】最新版11.0.27・10.1.61・9.0.123とCVE-2026-59083ほかの影響確認・対応手順
  2. 2026.10.22 テックブログ Tomcatバージョン一覧とサポート期限【2026年10月】9.0系は2027年3月末で終了・9.1系と11.0系への移行判断
  3. 2026.10.21 テックブログ NEC委託先の不正アクセスとは|顧客システム暗号化・情報漏えいの経緯と委託元が点検する正規アカウント
  4. 2026.05.15 テックブログ scrcpyの最新版は5.0|ハードウェアデコード対応とインストール・使い方【2026年10月】
  5. 2026.10.21 テックブログ ふるさとチョイス不正アクセスで445万件流出:対象確認・パスワード変更と再開時期

RELATED POSTS 関連記事

目次