こんにちは、香田です。
今回は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-ray
Dockerfileを作成します。
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/install
docker-compose.ymlを作成します。
version: "3"
services:
serverless:
build: .
image: serverless
container_name: serverless
env_file:
- .env
tty: true
volumes:
- "./:/app"
working_dir: /app
AWS認証情報を定義した.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 bash
serverlessコマンドの実行確認。
serverless --version
AWSサーバーレス環境の構築
SQSを作成します。
aws sqs create-queue --queue-name serverless-app-queue
aws-xray-sdk
をインストールし、requirements.txtを作成します。
pip install aws-xray-sdk
pip freeze > requirements.txt
Lambda 関数コードとして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-requirements
Serverless Frameworkでは下記の箇所をtrue
に設定することで、API Gateway、Lambdaのトレース設定が有効化されます。
tracing:
apiGateway: true
lambda: true
serverless-python-requirements
プラグインをインストールし、requirements.txtの外部パッケージも同梱されるようにします。
serverless plugin install -n serverless-python-requirements
準備ができたので、AWS環境へデプロイします。
serverless deploy -v
X-Rayの確認
デプロイが完了したら、API Gatewayへリクエストをしばらく送信しX-Rayでトレースデータが表示されるか確認します。
API GatewayのIDを確認し環境変数へ設定します。
export API_ID=xxxx
GET リクエストの送信確認。
curl -s -X GET https://$API_ID.execute-api.ap-northeast-1.amazonaws.com/dev/hello | jq .message
POST リクエストの送信確認。
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 -v
SQSを削除します。
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サービスなどの実行状況やパフォーマンスを把握したい場合有用ではないでしょうか。
最後までご覧いただきありがとうございます。