この記事は「もくもく会ブログリレー」 4日目 の記事です。

X-Rayについて&導入の背景

Lambdaを中心とした構成でサービス運用している中で、

「CloudWatch Logsのメトリクスを見ると大幅なレスポンス遅延があったが、外部接続かアプリケーション側か、処理のどこで発生しているのかわからない」

という場面に遭遇することがあります。

こうした場合に役立つのがAWS X-Rayです。X-Rayではレスポンス待ち時間やサービス障害、リクエストパラメータとメタデータを収集できます。

コスト

気になるのは有効化したときのコストですが、リクエスト数次第ではほとんどお金はかかりません。

【永続的な無料利⽤枠】

  • 毎月、トレースの記録は 10 万回まで無料
  • 毎月、トレースの取得とスキャンは合わせて 100 万回まで無料

【無料枠超過後の追加料金】 ※東京リージョン

  • トレース記録コスト 5.00USD (トレースあたり 0.000005 ドル)
  • トレース取得コスト 0.50USD 件 (1 トレースあたり 0.0000005 ドル)
  • スキャンされたトレースコスト 0.50USD (トレースあたり 0.0000005 ドル)

※上記は2024/06/26時点の情報です
AWS X-Ray の料金

使用方法は3種類

X-Rayを使用する方法には以下の3種類があります。

  1. AWSコンソール
  2. SDKを使用する
  3. X-Ray APIを使用する

①のAWSコンソールについては、有効化したいサービスからコンソール上で有効化にチェックを入れるだけなので、説明は割愛します。

Lambdaの例

②のSDKには、ADOT SDKとX-Ray SDKの2つが用意されています。詳細は公式ドキュメントに記載されていますが、ADOTを使う必要がない場合はX-Ray SDKを使用します。
※ADOTについてはこちら参照

X-Ray SDK を既に使用していて、バックエンドと AWS のみ統合し、X-Ray またはアプリケーションコードの操作方法を変更しない場合は、X-Ray SDK を使用します。

③のX-Ray APIは、SDKが使用しているプログラミング言語に対応していない場合の選択肢です。X-Ray APIを直接叩くか、AWS CLIを使用してAPIを呼び出します。
詳細はこちら

実際に有効化してみる

以下のようなアーキテクチャを想定して、X-Rayを有効化してみます。

X-Rayを有効化するとこんな感じで見れます。

今回Lambdaから呼んでいるサービスは、SDKを使ってトレースしています。
※X-Rayでは、API GatewayはREST APIのみトレース可能です。

X-Rayは、 API Gatewayを介したREST APIの追跡のみをサポートしています。
https://docs.aws.amazon.com/ja_jp/xray/latest/devguide/xray-services-apigateway.html

サポートされている他サービスは以下です。
※2024/06/26時点

  • Amazon EC2
  • AWS App Mesh
  • AWS App Runner
  • AWS AppSync
  • AWS CloudTrail
  • Elastic Load Balancing
  • Amazon EventBridge 他

詳細はインテグレーションAWS X-Ray他とAWS のサービスを参照してください。

X-Rayを有効化する

AWS SAMを使用してLambdaとAPI GatewayのX-Rayを有効化します。

Lambdaの設定

TracingActiveまたはPassThroughに設定します。
今回はActiveにしていますが、特定のトレースヘッダーがある場合のみトレースしたい場合はPassThroughに設定します。
ActiveとPassThroughの違いの詳細はこちら

Function:
  Tracing: Active

X-Rayにトレースデータを送信するポリシーを追加します。

Effect: "Allow"
Action:
  - "xray:PutTraceSegments"
  - "xray:PutTelemetryRecords"
Resource: "*"

API Gatewayの設定

TracingEnabledTrueに設定します。
※デフォルトはFalse

Api:
  TracingEnabled: True

ここまでで、API GatewayとLambdaの設定は終わりです。現状では、この2つのサービスしかトレース対象にならないため、Lambdaで呼び出しているサービスも対象とするためにSDKを使用します。

Lambdaが呼び出しているサービスもトレース対象にする(Python)

呼び出しているサービスを全てトレースする場合は、patch_all()をコードに追加します。

from aws_xray_sdk.core import patch_all

patch_all()

全体ではなく、特定のAWSサービスのみを対象としたい場合は以下のように記述します。

from aws_xray_sdk.core import patch

libraries = (["boto3"])
patch(libraries)

外部APIもトレース可能

AWS外のAPIを呼び出している場合もX-Rayでトレースが可能です。
ここではLambdaからQiitaのAPIを呼び出してみます。

実行した際のX-Rayの画面は以下のようになります。

注意点

SDKにおけるRDSのトレース(Python)

今回は使用していませんが、もしRDSのトレースを行いたい場合は、サポートしてるライブラリが限られているので確認必須です。

例: python

botocore、boto3
pynamodb
aiobotocore、aioboto3
requests、aiohttp
httplib、 http.client
sqlite3
mysql-connector-python
pg8000
psycopg2
pymongo
pymysql

詳しくはAWS X-Ray SDK for Python参照

 

トレース全般に関する注意

① サンプリングはデフォルトのサンプリングルールで実行される

AWS X-Rayでは、デフォルトのサンプリングルールに従ってリクエストが記録されます。このルールでは「1秒ごとに最初のリクエストは必ずトレース」されます。つまり、1秒間に2回リクエストされた場合、2回目のリクエストがトレースされる保証はありません。100%トレースする設定も可能ですが、その場合は料金とパフォーマンスへの影響を確認する必要があります。​

②データの完全性は保証されない

AWS X-Rayは監査やコンプライアンスのツールとして使用することはできないと公式ドキュメントに書かれています。収集されるデータは統計的に有意なリクエスト数に基づいていますが、データの完全性は保証されません。

③ 直近30日間のみ追跡データを保存

AWS X-Rayは、トレースデータを直近30日間のみ保存するという制限があります。このため、長期的な分析や監査には適していません。重要なデータは別の方法で保存する必要があります。

 

おまけ:X-Rayの有効/無効をtemplate.ymlで制御してみる

やや可読性は落ちますが、AWS SAMで環境ごとに有効/無効を制御することも可能です。

以下はConditionsで”on”(有効)かどうかの条件を定義し、TrueであればAPI GatewayとLambdaのX-Ray設定を有効にする設定を入れています。

Conditions:
  IsEnabledXRayTracing: !Equals [ XRayEnableFlag, "true" ]

Globals:
  Function:
    Tracing: !If [ IsEnabledXRayTracing, Active, Disabled ]
    Environment:
        Variables:
            XRAY_ENABLE_FLAG: "true"  // または "false" に設定することで設定変更

  Api:
    TracingEnabled: !If [ IsEnabledXRayTracing, True, False ]

Resources:
  LambdaRole:
    Type: AWS::IAM::Role
    Properties:
      Policies:
        -
          PolicyName: lambda
          PolicyDocument:
            Version: "2012-10-17"
            Statement:
              - !If
                - IsEnabledXRayTracing
                -
                  Effect: "Allow"
                  Action:
                    - "xray:PutTraceSegments"
                    - "xray:PutTelemetryRecords"
                  Resource: "*"
                - !Ref "AWS::NoValue"

まとめ

Lambdaのどの処理でレスポンスに遅延が発生するかを特定できてX-Ray最高!
ただ30日でログが追えなくなるので注意が必要です。

明日のもくもく会ブログリレー記事は、Yuutakkumaさんです!