この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。
ども、藤本です。
AWS X-Ray はアプリケーションのパフォーマンスを簡単にモニタリングすることができるサービスです。EC2上で動作するアプリケーションや、AWS Lambda で動作するファンクションに簡単に組み込むことができます。
元々、Java、Node.js、.NET は SDK をリリースされていましたが、現地時間 2017/08/08 に Python SDK がリリースされました。
Python SDK を使って、どういう時にどういう実装をすればいいのか色々と試してみました。
色々と試してみた
AWS X-Ray を知らない方はコンセプトのドキュメントページを一読いただくことをオススメします。
環境
- 環境 : Amazon EC2
- OS : Amazon Linux
- Python : 2.7.12
- X-ray SDK : 0.92
事前準備
事前に X-Ray デーモン、SDK、および boto3 をインストールします。また EC2 には X-Ray の権限を付与した IAM ロールを設定します。
$ sudo yum install -y https://s3.dualstack.ap-northeast-1.amazonaws.com/aws-xray-assets.ap-northeast-1/xray-daemon/aws-xray-daemon-2.x.rpm
$ sudo pip install aws-xray-sdk boto3
事前準備が終わったら、色々と試していきましょう。
セグメント作成(任意の処理のパフォーマンスを計測する)
まずはベースとなるセグメントを作成して、任意の処理のパフォーマンスを計測してみましょう。計測したい処理の前後を aws_xray_sdk.core.xray_recorder
の begin_segment
と end_segment
で挟むだけです。
下記サンプルコードでは print
の処理時間を計測しています。
any_processing.py
#!/usr/bin/env python
from aws_xray_sdk.core import xray_recorder
def main():
xray_recorder.begin_segment('Any processing')
print('test message.')
xray_recorder.end_segment()
if __name__ == '__main__':
main()
それでは実行します。
$ chmod u+x any_processing.py
$ ./any_processing.py
test message.
X-Ray の UI から見てみましょう。Service Map を選択します。
begin_segment
に記載した Any processing の処理が記録されています。平均処理時間が 1ms 以下もないので 0ms になっていて分かりづらいので、View traces から詳細を確認します。
スクリプト実行なので URL は紐付いていません。
Trace list の ID を選択します。
0.13ms で処理完了していることがわかります。
こういった感じでプログラムにトレースコードを埋め込むことで簡単に任意の処理をトラッキングすることができます。
サブセグメント作成(セグメント内で各処理のパフォーマンスを計測する)
先ほど任意の処理を計測しました。大きな処理ブロックを計測しつつ、そこから細切れに計測したいケースもあるかと思います。例えば、処理全体を計測しつつ、DB の処理だけ、外部サービスの呼び出し部分だけを計測するような。サブセグメントを定義することでセグメント内の各処理を計測することができます。サブセグメント内にサブセグメントは定義できないようです。
begin_segment
と end_segment
の中に begin_subsegment
と end_subsegment
を追加します。
nest_processing.py
#!/usr/bin/env python
from aws_xray_sdk.core import xray_recorder
from time import sleep
def main():
xray_recorder.begin_segment('Nest processing')
sleep(1)
xray_recorder.begin_subsegment('sleep')
print('test message.')
xray_recorder.end_subsegment()
sleep(1)
xray_recorder.end_segment()
if __name__ == '__main__':
main()
スクリプトを実行します。
$ ./nest_processing.py
test message.
X-Ray の UI から見てみましょう。Trace を確認してみると、、、
階層構造でそれぞれの処理時間を確認することができます。
関数を計測する
プログラムの各所に開始と終了のコードを埋め込んでいくのは手間です。SDK では関数にデコレータを付与することで関数をサブセグメントとすることができます。関数型言語では目的毎に関数に切り出すケースが多いし、デコレータの方が分かりやすいと思うのでこの使い方が多くなりそうですね。
decorator_processing.py
#!/usr/bin/env python
from aws_xray_sdk.core import xray_recorder
from time import sleep
@xray_recorder.capture('sleep')
def output():
print('test message.')
def main():
xray_recorder.begin_segment('Decorator processing')
sleep(1)
output()
sleep(1)
xray_recorder.end_segment()
if __name__ == '__main__':
main()
スクリプトを実行して、X-Ray の UI から見てみましょう。Trace を確認してみると、、、
先ほどと同様の結果となります。
HTTP リクエスト別に計測する
セグメント化、サブセグメント化によって、一つのアプリケーションのステータスを確認できることがわかりました。次に Web リクエスト別でサービスグラフを表示します。Web API ベースのマイクロサービスアーキテクチャのようにサービス単位でアプリケーションが分割しているシステムの処理のトラッキングや、サービス正常性の確認に役立ちます。
SDK の patch
、patch_all
によりサポートされたライブラリ利用時にトラッキングされます。Web リクエストでは requests パッケージがサポートされています。
下記サンプルコードでは弊社HP、ブログのトップページへ HTTPS リクエストを送信して、レスポンスコードを表示しています。
web_request.py
#!/usr/bin/env python
from aws_xray_sdk.core import xray_recorder, patch, patch_all
import requests
patch_all()
#patch(['requests'])
def main():
xray_recorder.begin_segment('Web request processing')
print(requests.get('https://classmethod.jp/').status_code)
print(requests.get('https://dev.classmethod.jp/').status_code)
xray_recorder.end_segment()
if __name__ == '__main__':
main()
X-Ray の UI から見てみましょう。Service Map を確認してみると、、、
セグメントからそれぞれの Web リクエストが個別で表示され、成功/失敗のステータスをトラッキングすることができます。
トレースを開くと各処理の処理時間も表示されます。
Web リクエストのrequests
以外には下記のライブラリのトラッキングがサポートされています。
- AWS API リクエストのトラッキング : boto3、botocore
- SQLite クエリのトラッキング : sqlite3
- MySQL クエリのトラッキング : mysql-connector-python
まとめ
いかがでしたでしょうか?
今回は SDK の記述方法を覚えるためにスクリプトで試しましたが、AWS X-Ray SDK は Web アプリケーションフレームワークと連携することで URL とマッピングされ、更に強力なトラッキングを行うことができます。連携可能な Web アプリケーションフレームは Django、Flask といった著名な OSS と連携できます。次回は Django と連携して色々と試してみたいと思います。