こんにちは!サーバーワークスの松井です。
今回は、X-Ray Analytics画面にてUSERを表示させてデータをフィルタリングする方法について、紹介したいと思います。
USERとは
X-Rayは、トレーシングするプログラムを実行する際に、プログラムを実行するユーザーをデータに取り込んだ上でデータ送信することができます。
AWS X-Ray Analytics コンソールとのやり取り - AWS X-Ray
そうすることで、X-Rayのコンソール画面で確認する際に、USERの値によってフィルタリング検索することができるので、実行プログラムの状況を比較検証したりすることができます。
前提条件
本ブログは、このブログの延長戦になりますので、以下を実施してからご覧ください。
実施方法
USERデータを送信するためには、セグメントにUSERのフィールドを取り込む必要があります。
X-Ray SDK for Python を使用してセグメントに注釈とメタデータを追加する - AWS X-Ray
ローカル環境のプログラムに追記してみます。
execute_lambda.py
import json import boto3 from aws_xray_sdk.core import xray_recorder from aws_xray_sdk.core import patch patch(['boto3']) client = boto3.client('lambda') def main(event, context): document = xray_recorder.current_segment() document.set_user("U12345") data = { "id": "device_a", "data": [ { "id": 0, "temperature": 10 } ] } #Lambdaを実行 client.invoke( FunctionName='put-dynamodb', InvocationType='RequestResponse', LogType='Tail', Payload= json.dumps(data) ) return if __name__ == '__main__': xray_recorder.begin_segment("local-x-ray") main(None, None) xray_recorder.end_segment()
この状態で実行すると以下の用にUSER画面に送信データが表示されます。
次に、Lambda側のプログラムでも同様にできるか試してみます。
先程と同様にプログラムに追記してみます。
put-dynamodb.py
from aws_xray_sdk.core import patch_all from aws_xray_sdk.core import xray_recorder import boto3 dynamodb = boto3.resource('dynamodb') patch_all() def lambda_handler(event, context) -> None: document = xray_recorder.current_segment() document.set_user("U12345") items = [] items.append(event) table = dynamodb.Table("accept_data") with table.batch_writer() as batch: for data in items: batch.put_item(Item=data)
するとエラーが発生します。
"errorMessage": "FacadeSegments cannot be mutated.", "errorType": "FacadeSegmentMutationException",.....
このエラーの原因は、LambdaでX-Rayを有効にしている場合は、セグメントに対してコードからは関与できないことに起因します。
AWS Lambda と AWS X-Ray - AWS X-Ray
Lambda 関数とウェブアプリケーションの計測のもう 1 つの違いは、Lambda が作成して X-Ray に送信するセグメントは、関数コードで変更できないことです。サブセグメントを作成し、そこに注釈とメタデータを記録できますが、親セグメントに注釈とメタデータを追加することはできません。
サブセグメントを作成したらどうなるでしょうか。
サブセグメントは、コード内の特定の関数の状態についてより詳細に見ることができるセグメントと親子関係にあるような概念です。
コードを以下に変更して実行してみます。
document = xray_recorder.current_subsegment() document.set_user("U12345")
実行するとこちらもエラーとなります。
[ERROR] AttributeError: 'Subsegment' object has no attribute 'set_user'
set_userは、サブセグメントに対応していないようです。
以下のドキュメントを見ますと、セグメントは、userフィールドをオプションで入れることができるのに対して、サブセグメントには、userフィールドがないのでサブセグメントには、userを入れ込めないことを確認できます。
AWS X-Ray セグメントドキュメント - AWS X-Ray
注釈機能では、どうでしょうか。 USER画面に表示させることはできないですが、注釈データでuserを自分で設定することでuserをフィルタリングすることができるはずです。
put-dynamodb.py
from aws_xray_sdk.core import patch_all from aws_xray_sdk.core import xray_recorder import boto3 dynamodb = boto3.resource('dynamodb') patch_all() @xray_recorder.capture('lambda_event') def lambda_handler(event, context) -> None: document = xray_recorder.current_subsegment() document.put_annotation('user', 'U12345') items = [] items.append(event) table = dynamodb.Table("accept_data") with table.batch_writer() as batch: for data in items: batch.put_item(Item=data)
こちらは、実行は成功しました。
生データをみてみるとサブセグメントの欄にuserが入っていることが確認できます。
"subsegments": [ { "id": "xxxxxxx", "name": "lambda_event", "start_time": 1649300985.0695126, "end_time": 1649300985.3674273, "in_progress": false, "annotations": { "user": "U12345" },
検索をかけてみます。
annotation.user = "U12345"
該当するユーザーでフィルタリングすることができました。
結論
セグメントにコードから関与できるローカル環境では、X-Ray Analyticsで実行ユーザーを表示させることができました。
Lambdaでは、セグメントにコードから関与できないのでUSERのダッシュボードに実行ユーザーを表示させることはできませんが、サブセグメントと注釈を使うことで同等のフィルタリング機能を使うことができるので是非Lambdaで使う場合にはこちらを試してみてください。
松井 宏司
エンタープライズクラウド部
2022 2023 2024Japan AWS All Certifications Engineer
プロレス観戦が趣味