前回までのおさらい
前々回は、アプリケーションに手を入れずにパフォーマンスを計測する目的で、まずはサンプルAPIを作成しました。
その次に自動計装の第1弾として、ADOT / X-Rayを実装しました。
今回は、ADOT / X-Rayに代えてApplication Signalsを試してみます。
Application Signalsとは
いまひとつ、X-Rayとの関係性がわからなかったのでChatGPTに聞きながら整理してみました。
経緯
AWSが提供する観測可能性スタックが時代とともに下記の通り再編された。
2023年まで
- アプリケーション
↓ - OpenTelemetry SDK / ADOT
↓ - AWS X-Ray サービス ← トレース可視化の中心
↓ - CloudWatch メトリクス・ログと連携
2024年から
- アプリケーション
↓ - OpenTelemetry SDK / AWSOpenTelemetryDistro
↓ - Application Signals (CloudWatch 統合ダッシュボード)
└ 内部で X-Ray を使用してトレースを収集
まとめると
以前はX-Rayを用いてサービスの一部分を可視化していたものをSLOを含めたより上位のレベルで管理するために、Application Signalsが生まれた、ということでしょうか。
使い分け
使い分けというか、Application SignalsはX-Rayを包含しているので、
- トレーシング基盤: X-Ray(継続使用、内部化)
- UI/統合監視: Application Signals(メイン利用推奨)
となります。
実装
サンプルAPIにApplication Signalsを実装します。
SAMテンプレートの修正
template.yamlを修正します。
履歴を残すため、前回導入したADOT / X-Ray向けの記載はコメント化して残しておきます。
Parametersセクション
ADOT Node LayerとADOT Collector Extensionの記載を削除し、OTel Layerの設定を追記します。記載している内容はADOTの時とほぼ同じです。
Parameters:
# Change From ADOT / X-Ray To Appication Signals ----->
# 必須:ADOT Node.js ランタイム Layer の ARN(リージョン/アーキ用)
# AdotNodeLayerArn:
# Type: String
# Default: "arn:aws:lambda:ap-northeast-1:615299751070:layer:AWSOpenTelemetryDistroJs:9"
# Description: ADOT Node.js runtime layer ARN (match your region/arch)
# AdotCollectorLayerArn:
# Type: String
# Default: ""
# Description: ADOT Collector extension layer ARN (optional)
OtelLayerArn:
Type: String
Default: "arn:aws:lambda:ap-northeast-1:615299751070:layer:AWSOpenTelemetryDistroJs:9"
Description: OTel Layyer for Application Signals
#<-----
# Delete for Application Signals----->
# # OTLP エンドポイント(Collector Extension使うなら http://127.0.0.1:4318 を推奨)
# OtelOtlpEndpoint:
# Type: String
# Default: http://127.0.0.1:4318
# Description: OTLP endpoint (e.g., http://127.0.0.1:4318 or https://collector.example:4318)
#
# # OTLP プロトコル
# OtelOtlpProtocol:
# Type: String
# AllowedValues: ["http/protobuf", "grpc"]
# Default: http/protobuf
#
#Conditions:
# HasCollector: !Not [!Equals [!Ref AdotCollectorLayerArn, ""]]
#<-----
Globalsセクション
Application SignalsはOtelの設定も自動で管理されるということで、該当部分をコメントアウトします。
Globals:
Function:
Runtime: nodejs20.x
Timeout: 10
MemorySize: 128
Architectures: [x86_64]
Tracing: Active
CodeUri: .
Environment:
Variables:
TABLE_NAME: !Ref MessagesTable
QUEUE_URL: !Ref InboundQueue
# ---------- OTel共通 ----------
AWS_LAMBDA_EXEC_WRAPPER: /opt/otel-instrument
#Delete for Application Signals----->
# OTEL_PROPAGATORS: x-ray
# OTEL_RESOURCE_ATTRIBUTES: !Sub 'service.namespace=${AWS::StackName},aws.region=${AWS::Region}'
# OTEL_TRACES_EXPORTER: otlp
# OTEL_METRICS_EXPORTER: otlp
# OTEL_LOGS_EXPORTER: otlp
# OTEL_EXPORTER_OTLP_ENDPOINT: !Ref OtelOtlpEndpoint
# OTEL_EXPORTER_OTLP_PROTOCOL: !Ref OtelOtlpProtocol
# OTEL_TRACES_SAMPLER: parentbased_always_on
#<-----
Resourcesセクション
Application Signalsの有効化
下記の内容を追記して有効化します。
# --------- Appication Signals ----------
AppSignalsDiscovery:
Type: AWS::ApplicationSignals::Discovery
Properties: {}
Lambdaの設定変更
例としてEnqueue Lambdaの記載をあげます。
Lambda LayerからADOT向けの設定を削除し、OTel向けの設定を追記します。
ここも設定内容としてはADOTもOTelもほぼ同じです。
加えて、IAMの設定を追記しています。
# ---------- ① Enqueue ----------
EnqueueFunction:
Type: AWS::Serverless::Function
Properties:
FunctionName: !Sub '${AWS::StackName}-Enqueue'
Handler: src/enqueue/index.handler
Layers:
# Change From ADOT / X-Ray to Application Signals ----->
# - !Sub '${AdotNodeLayerArn}'
# - !If [HasCollector, !Sub '${AdotCollectorLayerArn}', !Ref "AWS::NoValue"]
Layers:
- !Ref OtelLayerArn
#<-----
Policies:
- AWSLambdaBasicExecutionRole
# Add For Appication Signals ----->
- arn:aws:iam::aws:policy/CloudWatchLambdaApplicationSignalsExecutionRolePolicy
#<-----
- SQSSendMessagePolicy:
QueueName: !GetAtt InboundQueue.QueueName
Events:
EnqueueGet:
Type: HttpApi
Properties:
ApiId: !Ref HttpApi
Path: /enqueue
Method: GET
ビルド & デプロイ
ビルド
ビルドします。
% sam build
デプロイ
デプロイします。
sam deploy \
--stack-name sam-test-stack \
--region ap-northeast-1 \
--capabilities CAPABILITY_IAM \
--no-confirm-changeset \
--resolve-s3 \
--parameter-overrides \
OtelLayerArn="arn:aws:lambda:ap-northeast-1:615299751070:layer:AWSOpenTelemetryDistroJs:9" \
OtelOtlpEndpoint=http://127.0.0.1:4318 \
OtelOtlpProtocol=http/protobuf
動作検証
デプロイできらた検証してみます。
APIの実行
テレメトリーデータを生成するため、APIにアクセスしてみます。(レスポンスは前回、前々回記事で取り上げているため割愛)
- キューイング
curl -sS "APIのURL/enqueue?msg=test"
- DynamoDBの中身を確認
curl -sS "APIのURL/items?limit=10" | jq .
マネージメントコンソールで確認
サービス
CloudWatch > Application Signals (APM) > サービスを開くと3つのLambdaが確認できます。
「Application Signalsを有効にする」ボタンをクリックしてみます。
「プラットフォームを指定」画面が表示されます。

「プラットフォーム欄で」Lambdaを選択すると、画面下部にLambdaの一覧が表示されます。今回Application Signalsを有効にしたLambdaは既にチェックが入っているためグレーアウトされているのがわかります。

トレースマップ
トレースマップを開くと、X-Rayの時と同様にAPIの各要素が表示されます。
トレース
トレースもX-Rayの時と一緒です。
Application Map
Lambda・ECS・API Gateway・DynamoDB・SQSなどの相互関係をノードとして可視化するグラフビューです。
左ペインを見ると、ステータスが500や400のものでフィルタすることもできるようです。
試しにWorker Lambdaを展開すると、Worker LambdaとDynamoDBが関連して表示されました。
まとめ
SAMでX-RayからApplication Signalsに切り替えることができました。
SLOの設定などは次回以降試したいと思います。





