📞

Apache / PHP-FPM構成のLaravelからCloudWatch Application Signalsにトレースを送信する方法

に公開

この記事は「AWS×OpenTelemetryについて調査&検証してみた連載」の第3回目です。

はじめに

前回は「CloudWatch Application Signalsにトレースを送信する構成パターン」という記事で、アプリケーションからCloudWatch Application Signalsにトレースを送信する7つの構成パターンを説明しました。

今回は、実際にアプリケーションからCloudWatch Application Signalsにトレースを送信してみます。

利用する環境

利用する環境は以下の通りです。

AWS環境:EC2 / Aurora
EC2 OS:Amazon Linux 2023
データベース: MySQL 8.0.39
Web/APサーバー:Apache / PHP-FPM
アプリケーション:Laravel 12.28.1

前回説明した構成パターンのうち、今回は「No.5:OTel + OTelCollector構成(OTLP形式)」でCloudWatch Application Signalsにトレースを送信します。

本記事の構成は以下の通りです。OpenTelemetry Collectorを利用しますが、簡易に検証するためアプリケーションと同じEC2にインストールします(本番環境では、別のインスタンスにインストールするのが良いと思います)。
また、PHPアプリケーションではよくある、WebサーバーとしてApacheを利用し、PHPの実行環境としてPHP-FPMを利用する構成にします。

本記事の構成
本記事の構成

Laravel環境の準備

Laravelの公式ドキュメントを参照して、EC2にLaravelをインストールします。DBアクセスを伴うユーザー認証機能を利用するため、認証機能を含むReactのスターターキットを選択してインストールします。合わせて、Apache / PHP-FPM構成でLaravelが起動するようにセットアップします。

インストール後、ブラウザで「/register」のURLにアクセスすると、以下のようなユーザー登録画面が表示されます。

Laravelスターターキットの画面
Laravelスターターキットの画面

これで、OpenTelemetryをセットアップする準備が整いました。

OpenTelemetryの設定

0. 前提準備

今回は、アプリケーションと同じEC2にOpenTelemetry Collectorをインストールし、X-RayのOTLPエンドポイントにトレースを送信するため、EC2に以下のIAMポリシーを含むIAMロールをアタッチします。

AWSXRayDaemonWriteAccess

1. PHP拡張のインストール

まず、OpenTelemetryのPHP拡張をインストールします。

pecl install opentelemetry

/etc/php.ini に以下を追記します。

php.ini
[opentelemetry]
extension=opentelemetry.so

2. OpenTelemetry関連のComposerパッケージのインストール

次に、OpenTelemetry関連のパッケージをインストールします。
Laravelプロジェクトのルートディレクトリで、以下を実行します。

composer config allow-plugins.php-http/discovery true
composer require open-telemetry/sdk
composer require open-telemetry/exporter-otlp
composer require guzzlehttp/guzzle php-http/guzzle7-adapter
composer require open-telemetry/opentelemetry-auto-laravel
composer require open-telemetry/opentelemetry-auto-psr15
composer require open-telemetry/opentelemetry-auto-psr18
composer require open-telemetry/opentelemetry-auto-guzzle

このうち、「open-telemetry/opentelemetry-auto-laravel」がLaravelでゼロコード計装を行うためのパッケージです。

3. 環境変数の設定

次に、OpenTelemetry関連の環境変数を設定します。PHP-FPMはそのままでは環境変数を読み込まないため、環境変数を受け渡すための設定をします。

以下の内容で、/etc/environmentを作成します。

environment
OTEL_PHP_AUTOLOAD_ENABLED=true
OTEL_SERVICE_NAME=laravel
OTEL_TRACES_EXPORTER=otlp
OTEL_EXPORTER_OTLP_PROTOCOL=http/protobuf
OTEL_EXPORTER_OTLP_TRACES_ENDPOINT=http://localhost:4318/v1/traces
OTEL_PROPAGATORS=baggage,tracecontext
OTEL_METRICS_EXPORTER=none
OTEL_LOGS_EXPORTER=none

以下の内容で、/etc/systemd/system/php-fpm.service.d/env.confを作成します。

env.conf
[Service]
EnvironmentFile=/etc/environment

/etc/php-fpm.d/www.confで、clear_env = noのコメントアウトを解除します。これで、環境変数を受け渡せるようになります。

www.conf
clear_env = no

最後に、設定を反映します。

sudo systemctl daemon-reexec
sudo systemctl restart php-fpm

これで、アプリケーション側の設定は完了です。

4. OpenTelemetry Collector(ADOT)のインストール

今回は、ADOTの公式ドキュメントに記載されている、Systems Manager Distributorを利用する方法でOpenTelemetry Collectorをインストールします。

https://aws-otel.github.io/docs/setup/ec2#install-aws-distro-for-opentelemetry-collector-on-ec2-instance-using-aws-systems-manager-distributor

OpenTelemetry Collector設定ファイルは以下の通りです。OTLPでトレースを受け付け、X-RayのOTLPエンドポイントにトレースを送信します。

receivers:
  otlp:
    protocols:
      http:
        endpoint: 0.0.0.0:4318

exporters:
  otlphttp:
    traces_endpoint: https://xray.ap-northeast-1.amazonaws.com/v1/traces
    compression: gzip
    auth:
      authenticator: sigv4auth

extensions:
  sigv4auth:
    region: ap-northeast-1
    service: xray

service:
  extensions: [sigv4auth]
  pipelines:
    traces:
      receivers: [otlp]
      exporters: [otlphttp]

上記をBase64に変換した文字列を、Systems Manager Parameter Storeに登録します。

名前:aoc-config-base64
タイプ:String
値:設定ファイルをBase64に変換した文字列

Systems Manager Parameter StoreへのOpenTelemetry Collectoer設定ファイル(Base64エンコード済み)の登録画面
Systems Manager Parameter StoreへのOpenTelemetry Collectoer設定ファイル(Base64エンコード済み)の登録画面

次に、Systems Manager DistributorからOpenTelemetry Collecterをインストールします。
Distributorの画面から、「Amazonが所有」タブで「AWSDistroOTel-Collector」を選択します。

Systems Manager DistributorでのAWSDistroOTel-Collector選択画面
Systems Manager DistributorでのAWSDistroOTel-Collector選択画面

「1回限りのインストール」をクリックし、Additional Arguments に{"SSM_CONFIG": "{{ssm:aoc-config-base64}}"}を入力して、LaravelをインストールしたEC2インスタンスにOpenTelemetry Collectorをインストールします。

Systems Manager DistributorでのAWSDistroOTel-Collectorのインストール画面(コマンドのパラメータ)
Systems Manager DistributorでのAWSDistroOTel-Collectorのインストール画面(ターゲット)
Systems Manager DistributorでのAWSDistroOTel-Collectorのインストール画面

これで、OpenTelemetry Collector側の設定も完了です。

5. CloudWatch Application Signalsの有効化

最後に、CloudWatch Application Signals側の設定です。初めて設定する場合は、以下のような画面が表示されるため、サービス検出の1回限りの設定をします。これは、CloudWatch Application Signalsにログやメトリクスにアクセスする権限を付与するための設定です。

CloudWatch Application Signalsのサービス検出画面

CloudWatch Application Signalsのサービス検出画面(ポップアップ)
CloudWatch Application Signalsのサービス検出画面

CloudWatch Application Signalsも有効化します。

CloudWatch Application Signalsの有効化画面
CloudWatch Application Signalsの有効化画面

また、X-RayのOTLPエンドポイントにトレースを送信して、CloudWatch Application Signalsで可視化するためには、X-Rayのトランザクション検索を有効化する必要があります。「Check this option to ingest spans as structured logs」にチェックを付け、今回はトレースをサンプリングしないため、Trace indexing rateは100%に設定します。

トランザクション検索の設定画面
トランザクション検索の設定画面

これで、CloudWatch Application Signalsにトレースを送信する準備が整いました。

トレースを送信してみる

それでは、実際にアプリケーションからCloudWatch Application Signalsにトレースを送信してみます。

Laravelからユーザーを作成し、ログインやログアウト等の操作をします。
初回は反映に少し時間が掛かりますが、CloudWatch Application Signalsの画面にサービスが表示されます。

CloudWatch Application Signals

また、トランザクション検索の画面を表示すると、リクエストやSQLのトレースが表示されています。

トランザクション検索

このトレースは、CloudWatch Logsのaws/spansロググループを参照しており、CloudWatch Logsからもトレースを確認することができます。

CloudWatch Logs

トランザクション検索から、「/login」のトレースを選択すると、そのトレースのマップやタイムラインが表示されます。HTTPリクエストのスパンや、そのリクエストによって実行されたSQLの子スパンを確認することができ、それぞれの所要時間等も可視化することができます。

トレースの詳細

SQLの子スパンを選択すると、実行されたSQLのサニタイズされたクエリも確認できます。

子スパンの詳細

まとめ

今回は、PHPを利用する場合によくあるApache / PHP-FPMの構成で、LaravelからCloudWatch Application Signalsにトレースを送信してみました。PHP-FPMはデフォルトでは、環境変数を読み込まないため、環境変数の受け渡しの工夫が必要でした。PHPでも比較的簡単にCloudWatch Application Signalsにトレースを送信できました。

本記事が、PHPでCloudWatch Application Signalsを利用する方の参考になれば幸いです。

参考

https://aws-otel.github.io/docs/setup/ec2
https://dev.classmethod.jp/articles/trace-laravel-on-ec2-by-opentelemetry/
https://speakerdeck.com/seike460/introduction-to-observability-with-opentelemetry
https://qiita.com/Tocyuki/items/9e4005d02cb0867b124a


ご意見やご指摘などありましたら、ぜひコメントで教えてください!

Discussion