この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。
一口に Lambda で X-Ray を有効化すると言ってもX-Ray アクティブトレースを有効化するだけもできますし、追加で AWS X-Ray SDK を利用してより詳細なトレーシングができます。
X-Ray で可視化したときにこの2パターンどのような違いがあるのでしょうか?また、X-Ray アクティブトレースを有効化するだけで得られるものは何か?違いを見比べてみましょう。
見比べた結果
Lambda コールドスタート時の様子を比較。クリックして拡大してみてね。
- X-Ray SDK 追加すると Lambda から呼び出しているサービス、処理もトレースできる
X-Ray 有効 | X-Ray SDK 追加 | |
---|---|---|
トレースマップ | ![]() |
![]() |
- X-Ray SDK 追加すると Lambda から呼び出しているサービス、処理にかかる時間を確認できる(緑枠の箇所が追加)
X-Ray 有効 | X-Ray SDK 追加 | |
---|---|---|
詳細 | ![]() |
![]() |
検証環境
AWSが提供しているハンズオンの構成をベースにX-Rayを追加します。ハンズオン自体は以前に「やってみたブログ」があるので以下を参考ください。
- サーバーレスアーキテクチャで翻訳 Web API を構築するハンズオンをやってみた | DevelopersIO
- AWS SAM を使ってテンプレートからサーバーレスな環境を構築するハンズオンをやってみた | DevelopersIO
初心者向けハンズオンで解説が非常に丁寧なため構成の解説はハンズオン動画にお任せします。追加した X-Ray について設定方法、可視化結果を解説します。
構成図
API Gateway の URL に POST すると API Gateway で受け付けて翻訳Lambdaを起動します。
画像引用: ハンズオンのアンケート回答後にダウンロードできる資料より
バージョン情報
ローカル端末で作成したSAMテンプレート、Lambda関数をsam deploy
でAWSへ展開します。
Product | Version |
---|---|
OS | macOS 11.6 |
SAM CLI | 1.36.0 |
Python | 3.9 |
aws-xray-sdk | 2.9.0 |
X-Ray なしの構成
ハンズオンの内容をベースに多少変更箇所がありますが概ね同じ内容です。簡単に説明します。
- Lambda に割り当ているポリシーが
FullAccess
ですので動作検証以外で参考にする場合は必要に応じて制限してください。 /translate
に対してリクエストメソッドがPOST
だと翻訳Lambdaが起動します。- リクエストボディを翻訳するのですがその処理は翻訳Lambda側になります。
template.yaml
AWSTemplateFormatVersion: "2010-09-09"
Transform: AWS::Serverless-2016-10-31
Description: Learn about X-Ray
Globals:
Function:
Timeout: 10
Resources:
TestLambda:
Type: AWS::Serverless::Function
Properties:
FunctionName: sample-function
CodeUri: ./sample
Handler: sample.lambda_handler
Runtime: python3.9
Architectures:
- x86_64
Timeout: 5
MemorySize: 256
Events:
PostApi:
Type: Api
Properties:
Path: /test
Method: get
RestApiId: !Ref TranslateAPI
TranslateLambda:
Type: AWS::Serverless::Function
Properties:
FunctionName: translate-function
CodeUri: ./translate-function
Handler: translate-function.lambda_handler
Runtime: python3.9
Architectures:
- x86_64
Timeout: 5
MemorySize: 256
Policies:
- TranslateFullAccess
- AmazonDynamoDBFullAccess
Events:
PostApi:
Type: Api
Properties:
Path: /translate
Method: post
RestApiId: !Ref TranslateAPI
TranslateAPI:
Type: AWS::Serverless::Api
Properties:
Name: translate-api
StageName: dev
EndpointConfiguration: REGIONAL
TranslateDynamoDbTbl:
Type: AWS::DynamoDB::Table
Properties:
BillingMode: PAY_PER_REQUEST
TableName: translate-history
AttributeDefinitions:
- AttributeName: timestamp
AttributeType: S
KeySchema:
- AttributeName: timestamp
KeyType: HASH
- Amazon Translate と利用して日本語から英語に翻訳します。
- 翻訳結果を DyanamoDB へ記録します。
- JSON 形式で翻訳結果が返ってきます。
translate-function.py
import json
import boto3
import datetime
translate = boto3.client(service_name='translate')
dynamodb_translate_history_tbl = boto3.resource(
'dynamodb').Table('translate-history')
def lambda_handler(event, context):
input_text = event['body']
response = translate.translate_text(
Text=input_text,
SourceLanguageCode="ja",
TargetLanguageCode="en"
)
output_text = response.get('TranslatedText')
dynamodb_translate_history_tbl.put_item(
Item={
"timestamp": datetime.datetime.now().strftime("%Y%m%d%H%M%S"),
"input": input_text,
"output": output_text
}
)
return {
'statusCode': 200,
'body': json.dumps({
'output_text': output_text
}),
'isBase64Encoded': False,
'headers': {}
}
実行結果は以下の通り。POSTしたリクエストボディを翻訳された結果のレスポンスを受け取ります。
$ curl -XPOST -d '網走出身です' https://api.example.com/v1/translate
{"output_text": "I'm from Abashiri"}⏎
X-Ray アクティブトレース有効化
SAMテンプレートでの X-Ray 有効化は手軽です。Lambda の他に API Gateway も利用しているので合わせて X-Ray を有効化します。
Globals
セクションに以下の様に追加するだけです。個別にAWS::Serverless::Function
や、AWS::Serverless::Api
のProperties
に追加しなくて済みます。
template.yaml
Globals:
Function:
Timeout: 10
Tracing: Active # Lambda での X-Ray 有効化
Api:
TracingEnabled: True # API Gateway での X-Ray 有効化
X-Ray デーモンを使用するために書き込み可能なアクセス権限を付与します。
TranslateLambda:
Type: AWS::Serverless::Function
Properties:
FunctionName: translate-function
CodeUri: ./translate-function
Handler: translate-function.lambda_handler
Runtime: python3.9
Architectures:
- x86_64
Timeout: 5
MemorySize: 256
Policies:
- TranslateFullAccess
- AmazonDynamoDBFullAccess
- AWSXRayDaemonWriteAccess
参考
SAMテンプレート全文
折りたたみ
AWSTemplateFormatVersion: "2010-09-09"
Transform: AWS::Serverless-2016-10-31
Description: Learn about X-Ray
Globals:
Function:
Timeout: 10
Tracing: Active # LambdaでのX-Ray有効化
Api:
TracingEnabled: True # API GatewayでのX-Ray有効化
Resources:
TestLambda:
Type: AWS::Serverless::Function
Properties:
FunctionName: sample-function
CodeUri: ./sample
Handler: sample.lambda_handler
Runtime: python3.9
Architectures:
- x86_64
Timeout: 5
MemorySize: 256
Policies:
- AWSXRayDaemonWriteAccess
Events:
PostApi:
Type: Api
Properties:
Path: /test
Method: get
RestApiId: !Ref TranslateAPI
TranslateLambda:
Type: AWS::Serverless::Function
Properties:
FunctionName: translate-function
CodeUri: ./translate-function
Handler: translate-function.lambda_handler
Runtime: python3.9
Architectures:
- x86_64
Timeout: 5
MemorySize: 256
Policies:
- TranslateFullAccess
- AmazonDynamoDBFullAccess
- AWSXRayDaemonWriteAccess
Events:
PostApi:
Type: Api
Properties:
Path: /translate
Method: post
RestApiId: !Ref TranslateAPI
TranslateAPI:
Type: AWS::Serverless::Api
Properties:
Name: translate-api
StageName: dev
EndpointConfiguration: REGIONAL
TranslateDynamoDbTbl:
Type: AWS::DynamoDB::Table
Properties:
BillingMode: PAY_PER_REQUEST
TableName: translate-history
AttributeDefinitions:
- AttributeName: timestamp
AttributeType: S
KeySchema:
- AttributeName: timestamp
KeyType: HASH
Lambda関数は変更することなくデプロイします。
デプロイ結果
Lambda の X-Ray アクティブトレースが有効化されています。
API Gateway の X-Ray トレースも有効化されています。
Lambda関数には全く手を入れないかたちで X-Ray を有効化しました。
X-Ray の結果
この設定だけでも可視化してくれます。
トレースマップは API Gateway と Lambda のみ表示されています。ですが、Lambda から Translate や、 DyanamoDB にアクセスしている様子はわかりません。
Lambda で X-Ray アクティブトレースを有効化すると以下の項目の取得、可視化ができます。
Initialization
: Lambda実行環境ライフサイクルの初期化フェーズです。- コールドスタートにかかる時間ですね。
Invocation
: Lambdaが関数ハンドラを呼び出すフェーズです。- ランタイムと拡張機能の登録から始まり、ランタイムがレスポンスを送信する準備ができた時点で終了します。
Overhead
: ランタイムがレスポンスを送信してから、次の呼び出しシグナルが送られるまでの間のフェーズです。
参考
X-Ray SDK for Python 追加
X-Ray SDK を Lambda関数に組み込んで違いを確認します。X-Ray SDK が対応しているライブラリに対しては以下の2行だけでパッチをあてることができます。これだけで AWS SDK を利用している Translate と、DyanamoDB は X-Ray のセグメントを自動作成してくれます、便利。
セグメントについては以下のリンクをご参照ください。
対応ライブラリ一覧
translate.py
import json
import boto3
import datetime
from aws_xray_sdk.core import patch_all
patch_all()
translate = boto3.client(service_name='translate')
X-Ray SDK for Python
ライブラリが必要になりますのでrequirements.txt
に書いておきます。
requirements.txt
aws-xray-sdk
X-Ray for Python 追加後のコード全文
折りたたみ
import json
import boto3
import datetime
from aws_xray_sdk.core import patch_all
patch_all()
translate = boto3.client(service_name='translate')
dynamodb_translate_history_tbl = boto3.resource(
'dynamodb').Table('translate-history')
def lambda_handler(event, context):
input_text = event['body']
response = translate.translate_text(
Text=input_text,
SourceLanguageCode="ja",
TargetLanguageCode="en"
)
output_text = response.get('TranslatedText')
dynamodb_translate_history_tbl.put_item(
Item={
"timestamp": datetime.datetime.now().strftime("%Y%m%d%H%M%S"),
"input": input_text,
"output": output_text
}
)
return {
'statusCode': 200,
'body': json.dumps({
'output_text': output_text
}),
'isBase64Encoded': False,
'headers': {}
}
SAMテンプレートの変更ないです。デプロイします。
X-Ray の結果
トレースマップが少し増えています。
Lambda関数で利用していた他AWSサービスが可視化されました。
invocation
が細分化され、translate
と DyanamoDB
の処理時間を確認できます。
翻訳に時間かかるケース
翻訳する文字量を大幅に増やしてリクエスト投げて比較してみます。
translate
の処理時間が275msから581msへ伸びていることを確認できます。どこの処理に時間がかかっているのか特定が容易ですね。
それとInitialization
の項目がないことを確認できます。連続して実行したためウォームスタートからの起動だったため、初期化の処理が走らなかった(コールドスタートではない)ことを確認できます。
まとめるとtranslate
の処理時間は長くなったもののInitialization
がなかったため、トータル実行時間は翻訳に時間かかるケースの方が早かったことが読みとれます。
おわりに
どういった違いがあるのか比較しておきたかったので冒頭にキャプチャを比較してあります。
今回はPythonのLambdaでしたが、AWS X-Ray SDK に対応したライブラリなら Lambda関数への追加もpatch_all()
だけで簡単ですね。