Amazon Web Services ブログ

CloudWatch 統合エージェントを使用した AWS X-Ray へのトレース送信

今日のアプリケーションは、かつてないほど分散化されており、もはや孤立して実行されることはありません。これは特に、Amazon Elastic Container Service (Amazon ECS) または Amazon Elastic Kubernetes Service (Amazon EKS) を利用する場合に当てはまります。分散型のワークロードやシステムとは、タスクやジョブを完了させるために連携する複数の小さな独立したコンポーネントで構成されるものです。これにより、1 つのシステムやコンポーネントが障害を起こしてもサービスの可用性に影響が及ばないようにします。分散型システムの追跡方法とは、クライアントサイドのリクエストがこれらのさまざまなコンポーネントを伝播する際の追跡方法で、レイテンシ、障害、その他のシステムエラーを特定するのに役立ちます。

エンドツーエンドの 分散トレーシングプラットフォームは、ユーザーがウェブサイトでフォームを送信したりクライアントリクエストが発生したりするとすぐにデータの収集を開始します。この際、初期のクライアントリクエストから発生したあらゆる上流の呼び出しを含みます。分散システムの需要が高まるにつれ、あらゆるレベルでのトレーシングの必要性も高まります。これを実装することで、サービス間の関係を理解し、特定のユーザーアクションを測定し、SLA を維持するなどのメリットがあります。

この記事では、トレースの基礎、AWS X-Ray とは何か、サンプルアプリケーションにロギング機能を追加してトレースを生成し、Amazon CloudWatch Agent をコレクターおよびエクスポーターとして使う方法について説明します。

トレースとは何か

トレースは、リクエストがサービスやシステムの様々なコンポーネントを経由する過程全体を表現します。トレースはオブザーバビリティの重要な柱であり、リクエストがシステムに入る際と抜ける際の詳細な流れを把握できるようになります。

ログやメトリクスとは異なり、トレースは 1 つ以上のシステムコンポーネントまたはサービスからのイベントで構成されています。トレースは、レスポンス待ち時間やサービス障害、リクエストパラメータとメタデータ (収集されているデータに関するさらなるコンテキストを提供) など、サービス間の接続に関するコンテキストを提供します。

AWS X-Ray は、これらのトレースの形式でデータを収集するサービスです。 X-Ray は、セグメントと呼ばれる形式でデータを受け取ります。セグメントには、コンポーネントまたはサービスが実行した作業やタスクの詳細が含まれており、1 つのトレースは複数のセグメントで構成されます。セグメントは、サブセグメントに分割され、より詳細なタイミングと、元のリクエストを満たすために行われたダウンストリームコール (外部 API 呼び出し、SQL クエリなど) に関する詳細が提供されます。 X-Ray は同じリクエストに関連するセグメントをグループ化してトレースにまとめます。

注意: OpenTelemetry (OTel) はスパンという概念を使用しますが、AWS X-Ray はセグメントという概念を使用します。トレーシングについて議論する際には、この 2 つの用語を読み替えて解釈してください。

AWS X-Ray は、これらのリクエストを表示、フィルター、洞察するための機能を提供します。アプリケーションに X-Ray を組み込むには、アプリケーションへの着信リクエスト、発信リクエスト、システムのパフォーマンスやエラー状況などの追跡情報を送信する必要があり、各リクエストに関するメタデータも送信します。アプリケーションに追跡情報を送信するための組み込み方法は、いくつかの方法があります。

  • 自動インスツルメンテーション – アプリケーションに対してコード変更が不要なインスツルメンテーション。アプリケーションに対する設定変更や自動インスツルメンテーション・エージェントの使用によって実現され、最も自動化されていてコード変更が少なくて済む手法です。
  • ライブラリインスツルメンテーション – 特定のライブラリやフレームワーク (AWS SDK、Apache HTTP クライアント、SQL クライアントなど) をターゲットとするプリビルトインスツルメンテーションを追加するために、最小限のアプリケーションコード変更が必要です。
  • 手動インスツルメンテーション – アプリケーションのトレース情報を送出する位置ごとにインスツルメンテーションコードを追加する必要があります。

CloudWatch エージェントとトレース

トレースデータが生成されると、コレクターがこのデータを収集、処理、エクスポートするために使用されます。コレクターは通常、3 つのコンポーネントで構成されています:

  1. レシーバ – このコンポーネントは、プッシュモデルまたはプルモデルでデータを受信します
  2. プロセッサ – データの集約、フィルタリング、サンプリング、その他のコレクタ処理ロジックを実行するのに使用されます
  3. エクスポータ – データが送られる予定の宛先 (例: AWS X-Ray) を定義するのに使用されます

コレクターは、システムコンポーネントのコードに、監視ツールが組み込まれたサービスからアプリケーショントレースを収集する機能を提供します。これは X-Ray SDK または OTel 言語固有の SDK (Python、Node.js、Java、Ruby、.NET など) を使用する場合で、開発者は選択した言語で OpenTelemetry API を使ってテレメトリデータを生成できます。

注意: コレクターはトレースの収集だけに使われるわけではなく、メトリクスとログにも利用され、収集、処理、及びさまざまなバックエンドへの出力が可能となります。

Amazon CloudWatch エージェント が、AWS X-Ray と OpenTelemetry トレース の収集をサポートするようになりました。以前は、トレースデータを収集するには、AWS 利用者が X-Ray デーモンを利用する必要がありましたが、これで利用者はメトリクス、ログ、トレースを用意するための単一のエージェントのみを設定すれば十分です。

ソリューションの概要

以下のアーキテクチャ図は、CloudWatch エージェントを収集エージェントとして利用した場合のフローを示しています。 X-Ray 独自の API と SDK を使ってトレースを送信することも可能ですが、この記事では OTel の利用に焦点を当てます。

Request flow

図 1 : リクエストの流れ

ウォークスルー

X-Ray へのトレース出力を開始するには、次の手順を実行してください。

  • X-Ray にトレースデータを送信できるようにする IAM ロールを作成します
  • 統合 CloudWatch エージェントをインストール、設定、起動します
  • OTLP を経由してトレースを出力するための Python アプリケーションをインストールし、利用します

前提条件

始める前に、以下の前提条件を満たす必要があります:

IAM ロールの作成

トレースを X-Ray に送信するには、EC2 インスタンスに AWSXRayDaemonWriteAccess AWS 管理ポリシーに含まれる次の X-Ray API を呼び出せる権限が必要です。また、AWS Session Manager を使用して EC2 インスタンスにアクセスできるように、AmazonSSMManagedInstanceCore ポリシーをも追加します。

以下に示す手順に従って、必要な IAM ロールを作成してください。

  1. IAM コンソール にログインします。
  2. 左側のペインで ロール を選択し、ロールを作成 をクリックします。
  3. 信頼されたエンティティタイプAWS のサービス を選択し、ユースケースで EC2 を選択して、次へ を選択します。
  4. 必要な権限ポリシーを追加するため、AWSXRayDaemonWriteAccess を検索して選択します。次に AmazonSSMManagedInstanceCore を検索して選択し、次へ をクリックします。
  5. ロール名を CWAgentTracingRole などに設定し、ロールを作成 をクリックします。
  6. 最後に、新しく作成したロールを EC2 インスタンスにアタッチします。手順については Attaching an IAM role to an instance ガイドを参照してください。

CloudWatch Agent のインストール

CloudWatch エージェントは、Amazon Simple Storage Service (Amazon S3) からエージェントパッケージをダウンロードしたり、AWS Systems ManagerAWS CloudFormation を使用したり、コマンドラインで手動でインストールしたりすることで、Linux、Windows、その他のサポートされているオペレーティングシステムにインストールできます。

Amazon Linux 2 リポジトリにあるエージェントを利用すると、yum パッケージマネージャを使って Linux ホストに 1 ステップでエージェントパッケージをインストールできます。これを行うには

  1. EC2 コンソールに移動し、インスタンスを選択してください。
  2. 次に 接続 をクリックし、セッションマネージャー を選択 -> 接続 をクリックしてください。
  3. セッションが開始したら、次のコマンドを実行して CloudWatch Agent をダウンロードし、インストールを実行してください。
sudo yum install amazon-cloudwatch-agent -y

CloudWatch エージェントの設定

CloudWatch エージェントの設定ファイルは JSON ファイルで、agentmetrics logstraces の 4 つのセクションがあります。
それぞれ異なる機能を持ちますが、このデモでは、以下のセクションに焦点を当てます。

  • agent セクションには、エージェントの全体的な設定のためのフィールドが含まれています。
  • traces セクションでは、収集され AWS X-Ray に送信されるトレースのソースを指定します。

X-Ray にトレースを送信するためには、エージェントを適切に設定する必要があります。エージェントの設定は手動で行うか、エージェントウィザードを使用して生成できます。

この記事の目的のために、手動での設定を実行します。Linux マシン上で作業する場合は、トラブルシューティングしやすくするため、設定ファイルに以下の名前を付けて、以下の場所に配置することをおすすめします。

/opt/aws/amazon-cloudwatch-agent/etc/amazon-cloudwatch-agent.json

Windows OS を使用している場合は、以下の場所に次の名前で指定してください。

プログラムデータフォルダ内のファイルパス: $ Env:ProgramData\Amazon\AmazonCloudWatchAgent\amazon-cloudwatch-agent.json

  1. 同じ Session Manager セッションを使用して、次のコマンドを実行します:
sudo nano /opt/aws/amazon-cloudwatch-agent/etc/amazon-cloudwatch-agent.json

2. 以下の JSON を CloudWatch Agent の設定ファイルにコピー&ペーストします。

{
    "agent": {
        "metrics_collection_interval": 60,
        "run_as_user": "root"
    },
    "traces": {
        "traces_collected": {
            "xray": {},
            "otlp": {}
        }
    }
}

3. 設定を保存し、キーボードショートカット ‘Ctrl + O‘ および ‘Ctrl + X‘ を使用してエディタを終了します。

上記の設定ファイルを使用してエージェントを起動するには、-a fetch-config オプションを指定して起動する必要があります。これにより、エージェントは最新の CloudWatch エージェント設定ファイルをロードします。また、-s オプションでエージェントが起動します。加えて、上記のセクションで作成した JSON ファイルへのパス参照 file: が必要です。

sudo /opt/aws/amazon-cloudwatch-agent/bin/amazon-cloudwatch-agent-ctl -a fetch-config -m ec2 -s -c file:configuration-file-path

次のコマンドを実行して、この設定で設定ファイルを作成し、エージェントを起動します。

sudo /opt/aws/amazon-cloudwatch-agent/bin/amazon-cloudwatch-agent-ctl -a fetch-config -m ec2 -s -c file:/opt/aws/amazon-cloudwatch-agent/etc/amazon-cloudwatch-agent.json

出力された設定ファイルを検証し、エージェントを起動します。確認するには、次のコマンドを実行してください。

sudo /opt/aws/amazon-cloudwatch-agent/bin/amazon-cloudwatch-agent-ctl -m ec2 -a status

図 2: ターミナルでのエージェントのステータス確認

インスタンスが X-Ray SDK または OTLP 経由のいずれかで、デフォルトのポートで着信トレースを待ち受けていることを確認できます。

次のコマンドを実行して確認してください。

sudo netstat -tulpn | grep LISTEN

図 3 : 現在のリスニングポートの確認 – Linux ターミナル

  • OTLP の場合
    • gRPC 経由の呼び出しはポート 4317 に送信されます
    • HTTP 経由の呼び出しはポート 4318 に送信されます
  • X-Ray SDK の場合
    • X-Ray SDK 経由の呼び出しはポート 2000 に行われます

トレースデータは、これらのポートにエージェントに送信されます。エージェントは、セグメントとスパンのデータを収集し、処理してこれらのトレースデータを AWS X-Ray にエクスポートします。

サンプル Python アプリケーションのインストール

OpenTelemetry トレースを生成するには、計装を行ってトレースをコレクタとして機能する CloudWatch Agent に送信するサンプルアプリケーションを作成する必要があります。aws-observability リポジトリこちら にある言語固有のさまざまなサンプルアプリケーションを含む Python アプリを使用します。

これを行うには

  1. EC2 インスタンスで、python-app.sh という名前のローカルファイルを作成します
  2. 次の bash スクリプトを貼り付けて保存します
#!/bin/bash 

 echo -e 'Installing Git... \n'
 sudo yum install git -y 

 echo -e 'Installing Pip... \n'
 sudo yum install pip -y 

 echo -e 'Cloning the GitHub Repo... \n'
 git clone https://github.com/aws-observability/aws-otel-community.git 

 echo -e 'Creating a virtual environment... \n'
 python3 -m venv ./ 

 echo -e 'Activating the virtual environment... \n'
 source bin/activate 

 echo -e 'Changing the directory... \n'
 cd aws-otel-community/sample-apps/python-manual-instrumentation-sample-app 

 echo -e 'Installing the requirements... \n'
 pip install --no-cache-dir -r requirements.txt 

 echo -e 'Starting the Python Application... \n'
 python app.py 

上記では、 git 、 pip 、必要な GitHub リポジトリをインストールし、Python の仮想環境と必要な依存関係も作成します。最後に Python アプリケーションを開始します。

3. sudo chmod u + x python-app.shを実行して、python-app.sh を実行可能にしてください

4. 次に、アプリケーションを起動するには、sudo ./python-app.sh を実行してください。

インストールが完了すると、次のような出力が表示されます。

図 4: 実行中のアプリケーション表示 – Linux ターミナル

サンプルアプリケーションが実行できたので、サンプルアプリケーションを実行することで、トレースを生成し X-Ray に出力できるようになりました。

OpenTelemetry トレースを X-Ray に送信

OpenTelemetry( OTel と呼ばれることもあります)はオープンソースのオブザーバビリティフレームワークです。システムの動作やパフォーマンスを分析するためのテレメトリデータを生成、収集、出力するための API、SDK、ツール群です。テレメトリデータの収集と送信方法を標準化している点が重要で、一貫した観測体験を実現し、ビジネス目標の達成に貢献します。

このエージェントは、OpenTelemetry プロトコル (OTLP) を利用して gRPC または HTTP 経由でデータを受信する役割を持ちます。データを受信すると、OpenTelemetry の Span は X-Ray Segments に変換され、PutTraceSegments API を介して X-Ray に送信されます。

この機能を実行するため、EC2 コンソールに戻り、前の手順と同じように EC2 インスタンスに新しい Session Manager セッションを作成します。ローカルの HTTP エンドポイントに HTTP リクエストを送るために、最初の 3 つのコマンドを順に実行します。

  • curl http://127.0.0.1:8080/
    • これで、アプリケーションが実行されていることを確認できます
  • curl http://127.0.0.1:8080/outgoing-http-call
    • これで、aws.amazon.com (http://aws.amazon.com/) へ HTTP リクエストを送信します
  • curl http://127.0.0.1:8080/outgoing-sampleapp
    • 最後に、これは <host>:<port>/outgoing-sampleapp で設定されているその他のすべてのサンプルアプリポートに呼び出しを行います。利用できるものがない場合は、www.amazon.com (http://www.amazon.com/) に HTTP リクエストを送信します

トレース ID が提供されていることから、リクエストは正常に実行されたことが確認できます。注意点: 各トレース ID はユニークであり、単一のクライアントリクエストに由来するすべてのセグメントとサブセグメントをつなげます。上記のようなリクエストを実行すると、ユニークなトレース ID が生成されます。詳細については、X-Ray セグメントドキュメンテーションを参照してください。

curl http://127.0.0.1:8080/
 OK 
 curl http://127.0.0.1:8080/outgoing-http-call 
{"traceId": "1-654b53e6-0d2fc7f829ccc9ef44cd1797"}
 curl http://127.0.0.1:8080/outgoing-sampleapp 
{"traceId": "1-654b53f9-3cc6cfa46c6367c7673d87ae"}

これらのトレースを確認するには、Session Manager の出力から traceId をコピーし、AWS コンソールの X-Ray トレースマップに移動してください。生成されたトレースは、コンソールで正しいリージョンが選択されていれば表示されます。

注意: トレースマップの時間範囲は、絶対時間範囲または相対時間範囲を指定することでも調整できます。

X-Ray トレースマップは、計装されたアプリケーションによって生成されたトレースデータの視覚的表現です。マップには、リクエストを処理したサービスノードと、リクエストの発信元となるアップストリームクライアントノード、さらにアプリケーションによって利用された Web サービスやリソースを表すダウンストリームサービスノードが表示されます。

図 5: サービスノードを示す AWS X-Ray トレースマップ

トレースセクションに移動し、生成されたトレースをクリックしてください。

図 6 : トレースされたリクエストを示す AWS X-Ray トレースコンソール

ここから、トレース ID の詳細、呼び出しのタイムスタンプ、レスポンスコード、レスポンス時間、継続時間、HTTP メソッド、URL アドレスが表示され、さらなる観察が可能です。

図 7 : 追跡されたリクエストを表示する AWS X-Ray Trace コンソール

これらの呼び出しは成功しましたが、AWS X-Ray は進行中の問題の調査に非常に役立ちます。では、トレースマップで見るとどのようになるでしょうか。

HTTP エンドポイントを呼び出すのと同じ SSM セッションを使って、次に、関連付けられたアカウントの S3 バケットを一覧するために、AWS S3 サービスを呼び出すコマンドを実行してください。

curl http://127.0.0.1:8080/aws-sdk-call

以下のような例外が発生すべきです。

<!doctype html> 
<html lang=en> 
<title>500 Internal Server Error</title> 
<h1>Internal Server Error</h1> 
<p>The server encountered an internal error and was unable to complete your request. Either the server is overloaded or there is an error in the application.</p>

上記の呼び出しへの応答から、アプリケーションが S3 サービスを呼び出しの際に問題が発生したことが明らかです。「トレースマップ」に移動し、エラーが発生したことを示すノード (ノードの赤い輪郭で強調表示) を見つけてください。

図 8: 失敗したリクエストをトレースしている AWS X-Ray トレースマップ

次に、トレースセクションに移動し、エラーを生成した traceId を検索します。トレースのステータスには Fault (5XX) と注釈が付けられています。そのトレースを選択すると、S3 ListBucket API を呼び出した際に生成された HTTP エラーコードの詳細が提供されます。

図 9 : 失敗したリクエストを示す AWS X-Ray トレースコンソール

トレース内で、HTTP 403 コードが観測されます。HTTP 403 は、権限の不足に関連する HTTP エラーコードです。このブログ記事の冒頭で説明したように、EC2 インスタンスに、インスタンスプロファイル IAM ロールを使って AWSXRayDaemonWriteAccess および AmazonSSMManagedInstanceCore AWS 管理ポリシーのみを付与しました。

この問題を解決するには、API を呼び出すための S3 の権限が必要です。IAM コンソールに戻り、先ほど作成した同じ IAM ロールに AmazonS3ReadOnlyAccess ポリシーを付与し、コマンドをもう一度実行してください。

curl http://127.0.0.1:8080/aws-sdk-call

必要な IAM の変更を行い、S3 API を呼び出せるようインスタンスを設定した後、トレースマップによって呼び出しが正常に行われたことを確認できます。

図 10 : 成功したトレース済みリクエストを示す AWS X-Ray トレースコンソール

クリーンアップ

予期せぬ請求を避けるため、テスト目的でのみインスタンスを作成した場合は、そのインスタンスを終了する必要があります。
そのためには、このデモの前または中で作成した EC2 インスタンスをコンソール または コマンドラインから終了してください。

まとめ

このポストでは、CloudWatch Agent が収集を行っているサンプルアプリケーションから、Python SDK を使ってトレースが X-Ray に送信される様子を見てきました。デベロッパーは、自動インスツルメンテーションを利用できます。これは、人手を介さずにさまざまなライブラリやフレームワークからのテレメトリデータを収集するために、動的にバイトコードをインジェクトすることで実現できます。OpenTelemetry を使った自動インスツルメンテーションは、C ++、.NET、Java、JS、Python などの様々なプログラミング言語でサポートされています。これは AWS EKS や ECS などのコンテナ環境でも実現できます。X-Ray は、AWS Lambda、Amazon API Gateway、Elastic Load Balancing など多くの AWS サービスと統合されています。詳しくはドキュメンテーションを参照してください。

より詳細を知りたい場合は、Amazon CloudWatch の機能のページを参照してください。
より実践的な経験を積みたい場合は、One Observability Workshop を受講したり、GitHub リポジトリのサンプルアプリを確認してください。

本記事は、Using the unified CloudWatch Agent to send traces to AWS X-Ray を翻訳したものです。翻訳は Solutions Architect の 津郷 が担当しました。