はじめに
AWS の X-Rayのトップページ を見ると
AWS との連携
AWS X-Ray は、Amazon EC2、Amazon EC2 Container Service (Amazon ECS)、AWS Lambda、AWS Elastic Beanstalk と連携します。Java、Node.js、および .NET で記述し、上記のサービスにデプロイされたアプリケーションに、X-Ray を使用できます。
と書かれていて「その環境でしか使えないの?」と思ってしまいましたが、ローカルPCでも使えます。オンプレのサーバーでも使えます。対応OSでインターネットに繋がっていれば。
というわけで、ローカルのWindows機で動かしてみます。
環境構築
こちら のX-Rayの構成図に描かれていますが、X-Ray は SDK から X-Ray daemon
にデータが送信され、daemon が AWS にデータを送信する仕組みになっています。
ローカルPCで daemon が動いていればOKです。
デーモンのダウンロード
こちら の デーモンのダウンロード
から。
今回は Windows (実行可能ファイル)
を選択しました。
Credential の設定
daemon がどのAWSアカウントにデータを送信するのかを設定しないといけません。
先ほどのページ の X-Ray にデータを送信するアクセス権限をデーモンに付与する
に書かれている通り、credentials ファイルにIAMユーザーのアクセスキーを設定します。
credentialsファイルは、通常は <ホームディレクトリ>/.aws/credentials
になります。
[default]
aws_access_key_id = アクセスキー
aws_secret_access_key = シークレットキー
どうやら自動的に [default]
プロファイルが使われるようで、複数のAWSアカウント・IAMユーザーを利用している人は、設定切り替えが少し面倒になるケースもあるかもしれません。
デーモン実行
ダウンロードしたzipを解凍。
cfg.yaml
で動作設定ができますが、ここでは変更なしで。
DOS
でデーモンのexeを実行。
> cd <xray_windows.exeのあるディレクトリ>
> .\xray_windows.exe -o -n ap-northeast-1
2019-06-19T14:20:19+09:00 [Info] Initializing AWS X-Ray daemon 3.0.1
2019-06-19T14:20:19+09:00 [Info] Using buffer memory limit of 80 MB
2019-06-19T14:20:19+09:00 [Info] 1280 segment buffers allocated
2019-06-19T14:20:19+09:00 [Info] Using region: ap-northeast-1
2019-06-19T14:20:19+09:00 [Info] Starting proxy http server on 127.0.0.1:2000
コマンドラインオプションについて。
-o
はローカルモード。ローカルPCで実行する場合は必須。
-n
でリージョン指定。どのリージョンの X-Ray にデータを送信するかをここで指定します。
このDOS窓は開きっぱなしにしておきます。
テストプログラム
Python3.6 のプログラムでお試しします。
必須ライブラリ
aws-xray-sdk
をインストール。
> pip install aws-xray-sdk
「LambdaでX-Rayを使ってみた」の記事 と同じように、インストールせずに必要なライブラリだけ配置する方法でもOKです。
ソース
「LambdaでX-Rayを使ってみた」の記事 と同じ処理内容。
SNSをpublishするたけのプログラムです。
import json
import boto3
from aws_xray_sdk.core import xray_recorder
from aws_xray_sdk.core import patch
patch(['boto3'])
def lambda_handler(event, context):
client = boto3.client("sns", region_name="ap-northeast-1")
print(client)
request = {
'TopicArn': "<SNS Topic の ARN>",
'Message': "test",
'Subject': "test"
}
response = client.publish(**request)
status_code = response['ResponseMetadata']['HTTPStatusCode']
# TODO implement
return {
'statusCode': 200,
'body': json.dumps('Hello from Lambda!')
}
if __name__ == '__main__':
xray_recorder.begin_segment("local-test_x-ray")
lambda_handler(None, None)
xray_recorder.end_segment()
Lambda function でお試ししたソースとの違いは、
xray_recorder.begin_segment("local-test_x-ray")
xray_recorder.end_segment()
を明示するところ。
そのため
from aws_xray_sdk.core import xray_recorder
も必須です。
begin_segment
が無いと、実行時にエラーになります。
end_segment
が無いと、エラーにはなりませんが、いつまでたってもデータ送信が行われません。
実行 & 結果
デーモンを動かしているDOSとは別にDOS窓を開いて、テストプログラムを実行
> python test_xray.py
正常に動作すれば、デーモンのDOSに以下のようなログが表示されます。
2019-06-19T14:48:13+09:00 [Info] Successfully sent batch of 1 segments (0.097 seconds)