こんにちは、香田です。
今回はAWSのサーバーレスサービスでX-Rayを設定する方法について紹介していきます。
サーバーレスアプリケーションを構築し、X-Rayを設定するとどういったことができるか簡単に紹介していきます。
AWS X-Rayとは
AWS X-Rayを使用するとアプリケーションやその基盤となるサービスの実行状況を把握することができ、パフォーマンスの問題やエラーの根本原因を特定し、トラブルシューティングに活用できます。
利用するAWS サーバーレスサービス
今回利用するAWS サーバーレスサービスは、API Gateway、Lambda、SQSとなります。
以降で下記構成を構築していきます。

ローカル開発環境の構築
API Gateway、Lambdaの構築はServerless Frameworkを利用していきます。
ローカル開発環境として、docker-composeを利用しServerless Frameworkを利用できるようにしていきます。
作業ディレクトリを作成します。
mkdir serverless-x-ray
cd serverless-x-rayDockerfileを作成します。
FROM node:latest
RUN apt-get update && \
apt-get install -y python3-pip less jq
RUN npm install -g serverless
RUN curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip" && \
unzip awscliv2.zip && \
./aws/installdocker-compose.ymlを作成します。
version: "3"
services:
serverless:
build: .
image: serverless
container_name: serverless
env_file:
- .env
tty: true
volumes:
- "./:/app"
working_dir: /appAWS認証情報を定義した.envファイルを作成します。
AWS_ACCESS_KEY_ID=xxxxx
AWS_SECRET_ACCESS_KEY=xxxxx
AWS_DEFAULT_REGION=ap-northeast-1各ファイル作成後、下記のような構成になっているはずです。
tree -a
.
├── .env
├── Dockerfile
└── docker-compose.ymlコンテナを起動しログインします。
docker-compose up -d
docker-compose exec serverless bashserverlessコマンドの実行確認。
serverless --versionAWSサーバーレス環境の構築
SQSを作成します。
aws sqs create-queue --queue-name serverless-app-queueaws-xray-sdkをインストールし、requirements.txtを作成します。
pip install aws-xray-sdk
pip freeze > requirements.txtLambda 関数コードとしてapp.pyという名前でファイルを作成します。
import os
import logging
import json
import boto3
from aws_xray_sdk.core import patch_all
from aws_xray_sdk.core import xray_recorder
xray_recorder.configure(service='serverless-app')
patch_all()
logger = logging.getLogger()
logger.setLevel(logging.INFO)
QUEUE_URL = os.getenv('QUEUE_URL')
SQS = boto3.client('sqs')
def hello(event, context):
body = {
"message": "Hello World",
"input": event
}
return {
"statusCode": 200,
"body": json.dumps(body)
}
def producer(event, context):
status_code = 200
message = ''
if not event.get('body'):
return {'statusCode': 400, 'body': json.dumps({'message': 'No body was found'})}
try:
SQS.send_message(
QueueUrl=QUEUE_URL,
MessageBody=event['body']
)
message = 'Message accepted!'
except Exception as e:
logger.exception('Sending message to SQS queue failed!')
message = str(e)
status_code = 500
return {
'statusCode': status_code,
'body': json.dumps({'message': message})
}
def consumer(event, context):
for record in event['Records']:
logger.info(f'Message body: {record["body"]}')X-Rayに関する設定は下記になります。
xray_recorder.configureでサービス名を定義し、patch_all()を設定することで、boto3、requests、psycopg2など下記でサポートされているライブラリのトレースデータを取得できます。
ダウンストリーム呼び出しを計測するためのライブラリへのパッチ適用
xray_recorder.configure(service='serverless-app')
patch_all()次にServerless Frameworkの設定ファイルであるserverless.ymlを作成します。
service: serverless-app
frameworkVersion: '2'
provider:
name: aws
runtime: python3.9
lambdaHashingVersion: 20201221
stage: dev
region: ap-northeast-1
tracing:
apiGateway: true
lambda: true
iamRoleStatements:
- Effect: Allow
Action:
- sqs:SendMessage
- xray:PutTraceSegments
- xray:PutTelemetryRecords
Resource:
- "*"
functions:
hello:
handler: app.hello
events:
- http:
path: /hello
method: get
producer:
handler: app.producer
events:
- http:
path: /producer
method: post
environment:
QUEUE_URL: https://sqs.${aws:region}.amazonaws.com/${aws:accountId}/serverless-app-queue
consumer:
handler: app.consumer
events:
- sqs: arn:aws:sqs:${aws:region}:${aws:accountId}:serverless-app-queue
plugins:
- serverless-python-requirementsServerless Frameworkでは下記の箇所をtrueに設定することで、API Gateway、Lambdaのトレース設定が有効化されます。
tracing:
apiGateway: true
lambda: trueserverless-python-requirementsプラグインをインストールし、requirements.txtの外部パッケージも同梱されるようにします。
serverless plugin install -n serverless-python-requirements準備ができたので、AWS環境へデプロイします。
serverless deploy -vX-Rayの確認
デプロイが完了したら、API Gatewayへリクエストをしばらく送信しX-Rayでトレースデータが表示されるか確認します。
API GatewayのIDを確認し環境変数へ設定します。
export API_ID=xxxxGET リクエストの送信確認。
curl -s -X GET https://$API_ID.execute-api.ap-northeast-1.amazonaws.com/dev/hello | jq .messagePOST リクエストの送信確認。
curl -s -X POST https://$API_ID.execute-api.ap-northeast-1.amazonaws.com/dev/producer \
--header 'Content-Type: application/json' \
--data-raw '{"name": "hello world"}' | jq .messageしばらくリクエストを送信後、X-Rayのコンソールより[Service Map]を確認すると下記のように表示されているはずです。
サービスマップを使用するとアプリケーションが処理するリクエストの流れを可視化することが可能です。
エラーが発生しているサービス、高レイテンシーの接続、失敗したリクエストのトレース等を識別できます。

X-Ray コンソールの[トレース]よりトレースリストを使用し、トレースの要約からURL、レスポンス、またはその他のデータによるトレースを検索できます。

下記のようにトレースIDを選択してトレースのタイムラインが表示可能です。

クリーンアップ
作成したAWSリソースを削除していきます。
Serverless Frameworkで作成したリソースを削除します。
serverless remove -vSQSを削除します。
export AWS_ACCOUT_ID=$(aws sts get-caller-identity --query Account --output text)
aws sqs delete-queue \
--queue-url https://sqs.ap-northeast-1.amazonaws.com/$AWS_ACCOUNT_ID/serverless-app-queueさいごに
AWSのサーバーレスサービスでX-Rayを設定する方法いかかでしたでしょうか?
数行の設定追加でX-Rayが使用可能なので、アプリケーションや利用しているAWSサービスなどの実行状況やパフォーマンスを把握したい場合有用ではないでしょうか。
最後までご覧いただきありがとうございます。